diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index acbfe33253b2..7f448c4dbbd0 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ # Update ARG and FROM together from the Node devcontainer image tags: # https://mcr.microsoft.com/en-us/product/devcontainers/javascript-node/tags ARG VARIANT=dev-24-bookworm -FROM mcr.microsoft.com/devcontainers/javascript-node:dev-24-bookworm@sha256:5ed0bf1411cffe8182ee6808477dd64c969a4ce78fee1b63e6a654d7deff889c +FROM mcr.microsoft.com/devcontainers/javascript-node:dev-24-bookworm@sha256:d0445b9546f96869b509aa70b8593bdc0054aca6689bc1dd0324083d0fd2bcc3 diff --git a/.github/actions/labeler/labeler.ts b/.github/actions/labeler/labeler.ts index 3f7589c2653c..9a0731a6b4ad 100644 --- a/.github/actions/labeler/labeler.ts +++ b/.github/actions/labeler/labeler.ts @@ -31,17 +31,8 @@ if (import.meta.url.endsWith(process.argv[1])) { ignoreIfLabeled: boolEnvVar('IGNORE_IF_LABELED'), } - // Actions pass comma-separated labels. - if (typeof ADD_LABELS === 'string') { - opts.addLabels = [...ADD_LABELS.split(',')].map((l) => l.trim()) - } else { - opts.addLabels = [] - } - if (typeof REMOVE_LABELS === 'string') { - opts.removeLabels = [...REMOVE_LABELS.split(',')].map((l) => l.trim()) - } else { - opts.removeLabels = [] - } + opts.addLabels = parseLabels(ADD_LABELS) + opts.removeLabels = parseLabels(REMOVE_LABELS) const actionContext = getActionContext() const { owner, repo } = actionContext @@ -58,6 +49,14 @@ if (import.meta.url.endsWith(process.argv[1])) { main(coreLib, octokit, opts) } +// Actions pass comma-separated labels, and an omitted input arrives as an empty string. +export function parseLabels(value?: string): string[] { + return (value || '') + .split(',') + .map((l) => l.trim()) + .filter(Boolean) +} + export default async function main( core: typeof coreLib | CoreInject, octokit: Octokit, diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b44f27721859..2ad74327f53f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -23,7 +23,9 @@ updates: ['version-update:semver-patch', 'version-update:semver-minor'] - package-ecosystem: 'github-actions' - directory: '/' + directories: + - '/' + - '/.github/actions/*' schedule: interval: weekly day: tuesday diff --git a/.github/workflows/auto-close-dependencies.yml b/.github/workflows/auto-close-dependencies.yml index a5fb729cbf88..3838dd684e25 100644 --- a/.github/workflows/auto-close-dependencies.yml +++ b/.github/workflows/auto-close-dependencies.yml @@ -9,6 +9,7 @@ on: - 'Gemfile*' - 'Dockerfile' - '.github/workflows/**' + - '.github/actions/**' permissions: contents: write diff --git a/.github/workflows/changelog-agent.yml b/.github/workflows/changelog-agent.yml index acf2240f0de7..1d02b16ef51d 100644 --- a/.github/workflows/changelog-agent.yml +++ b/.github/workflows/changelog-agent.yml @@ -227,10 +227,12 @@ jobs: const prNumber = parseInt('${{ steps.resolve_pr.outputs.pr_number }}', 10); const prAuthor = '${{ steps.resolve_pr.outputs.pr_author }}'; - const { data: reviews } = await github.rest.pulls.listReviews({ + // Approvals often come after many comment reviews, so read every page + const reviews = await github.paginate(github.rest.pulls.listReviews, { owner: context.repo.owner, repo: context.repo.repo, pull_number: prNumber, + per_page: 100, }); const approvedReviewers = [...new Set( diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5c31ec7b3c0a..641d523fbdd2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -32,7 +32,9 @@ jobs: with: languages: javascript - uses: github/codeql-action/analyze@e296a935590eb16afc0c0108289f68c87e2a89a5 # v4.30.7 - continue-on-error: true + # Pull request scans stay non-blocking so analysis errors do not hold up merges. + # Push runs must fail so the alert steps below fire. + continue-on-error: ${{ github.event_name == 'pull_request' }} - uses: ./.github/actions/create-workflow-failure-issue id: create-failure-issue diff --git a/.github/workflows/confirm-internal-staff-work-in-docs.yml b/.github/workflows/confirm-internal-staff-work-in-docs.yml index ba37bf449f4f..82355ca682a1 100644 --- a/.github/workflows/confirm-internal-staff-work-in-docs.yml +++ b/.github/workflows/confirm-internal-staff-work-in-docs.yml @@ -4,9 +4,9 @@ name: Confirm internal staff meant to post in public on: issues: + # Issues moved into github/docs arrive as opened. The transferred event fires in the source repo. types: - opened - - transferred # pull_request_target lets the workflow check org membership for forked PR authors. pull_request_target: types: diff --git a/.github/workflows/dont-delete-assets.yml b/.github/workflows/dont-delete-assets.yml index 3d10e2c54fd1..20d7b234cca2 100644 --- a/.github/workflows/dont-delete-assets.yml +++ b/.github/workflows/dont-delete-assets.yml @@ -44,6 +44,8 @@ jobs: - name: Update comment if: ${{ steps.comment.outputs.markdown != '' }} + # Fork PRs get a read-only token, so posting fails there. The next step still shows the instructions. + continue-on-error: true uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 with: comment-id: ${{ steps.findComment.outputs.comment-id }} @@ -53,7 +55,11 @@ jobs: - name: Ultimately fail the workflow for attention if: ${{ steps.comment.outputs.markdown != '' }} + env: + MARKDOWN: ${{ steps.comment.outputs.markdown }} run: | echo "More than 1 asset image was deleted as part of this PR." - echo "See posted PR commented about how to get them back." + echo "See the PR comment or this job's summary for how to get them back." + echo "$MARKDOWN" >> "$GITHUB_STEP_SUMMARY" + echo "$MARKDOWN" exit 1 diff --git a/.github/workflows/dont-delete-features.yml b/.github/workflows/dont-delete-features.yml index 172ba48603e8..7dac3139490d 100644 --- a/.github/workflows/dont-delete-features.yml +++ b/.github/workflows/dont-delete-features.yml @@ -42,6 +42,8 @@ jobs: - name: Update comment if: ${{ steps.comment.outputs.markdown != '' }} + # Fork PRs get a read-only token, so posting fails there. The next step still shows the instructions. + continue-on-error: true uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 with: comment-id: ${{ steps.findComment.outputs.comment-id }} @@ -51,7 +53,11 @@ jobs: - name: Ultimately fail the workflow for attention if: ${{ steps.comment.outputs.markdown != '' }} + env: + MARKDOWN: ${{ steps.comment.outputs.markdown }} run: | echo "This PR deletes or renames one or more feature files." - echo "See the PR comment for how to get them back." + echo "See the PR comment or this job's summary for how to get them back." + echo "$MARKDOWN" >> "$GITHUB_STEP_SUMMARY" + echo "$MARKDOWN" exit 1 diff --git a/.github/workflows/generate-code-scanning-query-lists.yml b/.github/workflows/generate-code-scanning-query-lists.yml index d1c447c287fc..ec26ed132a45 100644 --- a/.github/workflows/generate-code-scanning-query-lists.yml +++ b/.github/workflows/generate-code-scanning-query-lists.yml @@ -152,6 +152,11 @@ jobs: create-pull-request: if: github.repository == 'github/docs-internal' runs-on: ubuntu-latest + # Serialize publishing so a second run sees the first run's PR before it force-pushes. + # Pull request dry runs get their own group so they never queue behind or cancel a publisher. + concurrency: + group: ${{ github.workflow }}-query-table-publication-${{ github.event_name == 'pull_request' && github.run_id || 'publish' }} + cancel-in-progress: false permissions: contents: write pull-requests: write @@ -216,9 +221,6 @@ jobs: branchname=codeql-query-tables-${{ steps.codeql.outputs.OPENAPI_COMMIT_SHA }} - # Query the remote because actions/checkout with fetch-depth 1 omits other remote-tracking branches. - branchExists=$(git ls-remote --heads origin refs/heads/$branchname | wc -l) - # Pull request runs validate generated files without pushing branches. if [ "$DRY_RUN" = "true" ]; then echo "Dry-run mode when run in a pull request" @@ -226,17 +228,20 @@ jobs: exit 0 fi - if [ $branchExists -ne 0 ]; then - echo "Branch $branchname already exists in the remote repository." + # Check for an open PR before pushing so reruns do not overwrite commits added to it. + existing_pr=$(gh pr list --repo github/docs-internal --head "$branchname" --json number --jq '.[0].number') + if [[ -n "$existing_pr" ]]; then + echo "Pull request #$existing_pr already exists for branch $branchname. Skipping PR creation." exit 0 - else - git checkout -b $branchname fi + git checkout -b $branchname git add data/reusables/code-scanning/codeql-query-tables git add data/reusables/code-quality/codeql-query-tables git commit -m "Update CodeQL query tables" - git push -u origin $branchname + + # Force-push over a branch left by a failed attempt; this workflow exclusively owns these branches. + git push --force -u origin $branchname echo "Creating pull request..." gh pr create \ diff --git a/.github/workflows/index-general-search.yml b/.github/workflows/index-general-search.yml index 99a0261f6af8..6ec3b423bf42 100644 --- a/.github/workflows/index-general-search.yml +++ b/.github/workflows/index-general-search.yml @@ -203,12 +203,6 @@ jobs: curl --retry-connrefused --retry 5 ${{ env.ELASTICSEARCH_URL }}/_cat/indices?v curl --retry-connrefused --retry 5 ${{ env.ELASTICSEARCH_URL }}/_cat/indices?v - - name: Purge Fastly edge cache - env: - FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }} - FASTLY_SERVICE_ID: ${{ secrets.FASTLY_SERVICE_ID }} - run: npm run purge-fastly -- --surrogate-key api-search:${{ matrix.language }} - - name: Upload failures artifact if: ${{ steps.check-failures.outputs.has_failures == 'true' }} uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 diff --git a/.github/workflows/link-check-external.yml b/.github/workflows/link-check-external.yml index 376f6c8e5d5c..a72ff5e52650 100644 --- a/.github/workflows/link-check-external.yml +++ b/.github/workflows/link-check-external.yml @@ -34,6 +34,8 @@ jobs: env: ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} CACHE_MAX_AGE_DAYS: '7' + # The script checks github.com repo links through the REST API only when this is set. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | if [[ -n "${{ inputs.max_urls }}" ]]; then npm run check-links-external -- --max ${{ inputs.max_urls }} diff --git a/.github/workflows/link-check-internal.yml b/.github/workflows/link-check-internal.yml index fb14cf9115de..240d35fd9c20 100644 --- a/.github/workflows/link-check-internal.yml +++ b/.github/workflows/link-check-internal.yml @@ -124,20 +124,23 @@ jobs: } const report = JSON.parse(fs.readFileSync(reportFile, 'utf8')) - const allRedirectGroups = report.groups.filter(g => g.isWarning) + // Raw redirect targets can carry the checked version's prefix; replacementTarget does not. + // Skip strings that could break out of the inline code spans, since directives must stay exact. + const isSafe = s => typeof s === 'string' && s.length > 0 && !/[`\r\n]/.test(s) + const allRedirectGroups = report.groups.filter(g => + g.isWarning && g.fixStrategy === 'codemod' && + isSafe(g.target) && isSafe(g.replacementTarget) && isSafe(g.occurrences[0]?.file)) const redirectGroups = allRedirectGroups.slice(0, 10) if (redirectGroups.length === 0) { - core.info('No redirect groups found, skipping Copilot issue.') + core.info('No renamed redirects found, skipping Copilot issue.') return } const directives = redirectGroups.map(g => { const occ = g.occurrences[0] - const redirectTarget = occ?.redirectTarget ?? 'unknown' - const file = occ?.file ?? 'unknown' - const lines = (occ?.lines ?? []).join(', ') || 'unknown' - return `- Update \`${g.target}\` to \`${redirectTarget}\` in \`${file}\` (line(s): ${lines})` + const lines = (occ.lines ?? []).filter(Number.isInteger).join(', ') || 'unknown' + return `- Update \`${g.target}\` to \`${g.replacementTarget}\` in \`${occ.file}\` (line(s): ${lines})` }).join('\n') const artifactsUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/artifacts` diff --git a/.github/workflows/move-content.yml b/.github/workflows/move-content.yml index 0cf5ba6d4035..b0a817c3b0c7 100644 --- a/.github/workflows/move-content.yml +++ b/.github/workflows/move-content.yml @@ -6,13 +6,13 @@ on: pull_request: paths: - src/content-render/scripts/move-content.ts - - src/content-render/scripts/test-move-content.ts - - 'src/frame/lib/**/*.js' + - src/content-render/scripts/test-moved-content.ts + - 'src/frame/lib/**/*.ts' - .github/workflows/move-content.yml # Dependency changes can break the move-content script. - 'package*.json' - - src/fixtures/fixtures/content/get-started/ - - src/fixtures/fixtures/content/code-security/ + - 'src/fixtures/fixtures/content/get-started/**' + - 'src/fixtures/fixtures/content/code-security/**' permissions: contents: read @@ -50,8 +50,9 @@ jobs: env: ROOT: src/fixtures/fixtures run: | + # The trailing slash on the old path matches what shell tab completion adds. npm run move-content -- \ - src/fixtures/fixtures/content/code-security/getting-started \ + src/fixtures/fixtures/content/code-security/getting-started/ \ src/fixtures/fixtures/content/code-security/got-started npm run test-moved-content -- \ diff --git a/.github/workflows/no-response.yaml b/.github/workflows/no-response.yaml index bffeb590ad4e..2049c4106b35 100644 --- a/.github/workflows/no-response.yaml +++ b/.github/workflows/no-response.yaml @@ -20,11 +20,13 @@ jobs: runs-on: ubuntu-latest # Only run in the public repo, and skip automated comments. # Bot-authored issue_comment events are workflow chatter, not author responses. + # Scheduled runs often have a bot actor, so the actor check skips only comments. if: >- github.repository == 'github/docs' && - github.actor != 'docs-bot' && + (github.event_name != 'issue_comment' || + (github.actor != 'docs-bot' && github.actor != 'github-actions' && - !endsWith(github.actor, '[bot]') + !endsWith(github.actor, '[bot]'))) steps: - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 id: stale diff --git a/.github/workflows/notify-about-deployment.yml b/.github/workflows/notify-about-deployment.yml index c025debd6f09..dc21174c3ab9 100644 --- a/.github/workflows/notify-about-deployment.yml +++ b/.github/workflows/notify-about-deployment.yml @@ -37,6 +37,8 @@ jobs: timeout-minutes: 5 env: GITHUB_TOKEN: ${{ secrets.DOCS_BOT_PAT_BASE }} + # Manual Purge Fastly runs carry no deploy, so the script reads /_build instead. + DEPLOY_SHA: ${{ github.event.workflow_run.event == 'deployment_status' && github.event.workflow_run.head_sha || '' }} run: npm run find-past-built-pr - uses: ./.github/actions/create-workflow-failure-issue diff --git a/.github/workflows/orphaned-files-check.yml b/.github/workflows/orphaned-files-check.yml index 5cbbf71b4a2b..b45c33477f19 100644 --- a/.github/workflows/orphaned-files-check.yml +++ b/.github/workflows/orphaned-files-check.yml @@ -9,15 +9,17 @@ on: - cron: '20 16 * * 1' pull_request: paths: - - .github/workflows/orphaned-assets-check.yml - .github/workflows/orphaned-files-check.yml # Dependency changes can break the orphaned-files scripts. - 'package*.json' - src/assets/scripts/find-orphaned-assets.ts - - src/content-render/scripts/reusables-cli/find/unused.ts + - src/content-render/scripts/reusables-cli.ts + - 'src/content-render/scripts/reusables-cli/**' + - src/content-linter/lib/helpers/liquid-utils.ts - src/data-directory/scripts/find-orphaned-tables.ts - src/workflows/walk-files.ts - src/languages/lib/languages.ts + - src/languages/lib/languages-server.ts - .github/actions/clone-translations/action.yml - .github/actions/node-npm-setup/action.yml @@ -53,7 +55,9 @@ jobs: # The -s flag keeps npm script-alias noise out of the file lists. assetFilesToRemove=$(npm run -s find-orphaned-assets) - reusableFilesToRemove=$(npm run -s reusables -- find unused | grep '^data/reusables' || true) + # Keep the CLI out of the pipeline so set -e catches its failures; grep may match nothing. + reusablesOutput=$(npm run -s reusables -- find unused) + reusableFilesToRemove=$(printf '%s\n' "$reusablesOutput" | grep '^data/reusables' || true) tableFilesToRemove=$(npm run -s find-orphaned-tables) [ -z "$assetFilesToRemove" ] && [ -z "$reusableFilesToRemove" ] && [ -z "$tableFilesToRemove" ] && exit 0 diff --git a/.github/workflows/reviewers-docs-engineering.yml b/.github/workflows/reviewers-docs-engineering.yml index d253c2553af4..4424239f8a41 100644 --- a/.github/workflows/reviewers-docs-engineering.yml +++ b/.github/workflows/reviewers-docs-engineering.yml @@ -61,12 +61,19 @@ jobs: PR_NUMBER: ${{ github.event.pull_request.number }} CHANGED_FILES: ${{ github.event.pull_request.changed_files }} REPO: ${{ github.repository }} + EVENT_ACTION: ${{ github.event.action }} run: | if [ "$PR_AUTHOR" = "dependabot[bot]" ] || [ "$PR_AUTHOR" = "docs-bot" ]; then echo "Author is $PR_AUTHOR; skipping lockfile churn detection." echo "lockfile_only=false" >> "$GITHUB_OUTPUT" exit 0 fi + # Removing the lockfile-churn-only label and reopening the PR is the documented override. + if [ "$EVENT_ACTION" = "reopened" ]; then + echo "PR reopened; skipping lockfile churn detection." + echo "lockfile_only=false" >> "$GITHUB_OUTPUT" + exit 0 + fi # `gh pr diff` fails above 300 files, and `gh pr view --json files` stops at 100. changed=$(gh api --paginate "repos/$REPO/pulls/$PR_NUMBER/files" --jq '.[].filename') echo "Changed files:" @@ -101,7 +108,7 @@ jobs: git push ``` - If the lockfile change is intentional, remove the `lockfile-churn-only` label and push or reopen the PR so this workflow sends it to the engineering review board. + If the lockfile change is intentional, remove the `lockfile-churn-only` label, then close and reopen the PR so this workflow sends it to the engineering review board. EOF gh pr comment "$PR" --body-file /tmp/lockfile-churn-body.md gh pr edit "$PR" --add-label lockfile-churn-only diff --git a/.github/workflows/send-to-triage-board.yml b/.github/workflows/send-to-triage-board.yml index d5bda9b77e7f..defd550489bb 100644 --- a/.github/workflows/send-to-triage-board.yml +++ b/.github/workflows/send-to-triage-board.yml @@ -2,6 +2,7 @@ name: Add new issues and PRs to central triage board # Adds new, reopened, and ready-for-review github/docs work to the Central Triage Group board. # Sets today's date so first responders can triage it. +# Skips PRs opened by docs-bot, such as Repo sync PRs, because they never need triage. on: issues: @@ -15,7 +16,7 @@ permissions: jobs: add-to-central-triage: runs-on: ubuntu-latest - if: github.repository == 'github/docs' + if: github.repository == 'github/docs' && github.event.pull_request.user.login != 'docs-bot' steps: - name: Triage to central triage board env: diff --git a/.github/workflows/triage-stale-check.yml b/.github/workflows/triage-stale-check.yml index 83a8d585cff7..b04ce765881d 100644 --- a/.github/workflows/triage-stale-check.yml +++ b/.github/workflows/triage-stale-check.yml @@ -26,11 +26,11 @@ jobs: days-before-close: 7 stale-issue-message: 'A stale label has been added to this issue, because it has been open for 30 days with no activity. If you think this issue should remain open, please add a new comment.' - exempt-issue-labels: 'help wanted,never-stale,waiting for review' + exempt-issue-labels: 'help wanted,never-stale,waiting for review,needs SME' stale-issue-label: 'Inactive' close-issue-label: 'Closed as inactive' - exempt-pr-labels: 'never-stale,ready to merge,waiting for review' + exempt-pr-labels: 'never-stale,ready to merge,waiting for review,needs SME' stale-pr-message: 'A stale label has been added to this pull request because it has been open 30 days with no activity. If you think this pull request should remain open, please add a new comment.' stale-pr-label: 'Inactive' close-pr-label: 'Closed as inactive' diff --git a/.github/workflows/validate-openapi-check.yml b/.github/workflows/validate-openapi-check.yml index aa0edd90bef4..3207a167c1bc 100644 --- a/.github/workflows/validate-openapi-check.yml +++ b/.github/workflows/validate-openapi-check.yml @@ -8,8 +8,9 @@ on: paths: - 'Dockerfile.openapi_decorator' - 'src/rest/scripts/openapi-check.ts' - - 'src/rest/scripts/utils/get-operations.ts' - - 'src/rest/scripts/utils/operation.ts' + # The check runs operation.ts and the helpers it imports. + - 'src/rest/scripts/utils/*.ts' + - 'src/tests/lib/validate-json-schema.ts' - 'src/rest/fixtures/openapi-check-fixture.json' - 'package.json' - 'package-lock.json' diff --git a/.gitignore b/.gitignore index 326e03a9547a..9e7e1629deb0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ # Node.js version specification .node-version +.nvmrc # getRemoteJSON() disk cache for archived content .remotejson-cache/ diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/CHANGELOG.md b/CHANGELOG.md index fc3ef7444d06..9c9c8b74de90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -129,7 +129,7 @@ LSP servers greatly improve Copilot CLI's ability to work with your code. For ex We've added documentation to explain LSP servers in greater detail and show how to install these for Copilot CLI: -* [Using LSP servers with GitHub Copilot CLI](https://docs.github.com/copilot/concepts/agents/copilot-cli/lsp-servers) +* [Using LSP servers with GitHub Copilot CLI](https://docs.github.com/copilot/concepts/customizations/lsp-servers) * [Adding LSP servers for GitHub Copilot CLI](https://docs.github.com/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers)
diff --git a/content/admin/troubleshooting-your-instance/index.md b/content/admin/troubleshooting-your-instance/index.md index f9aec76eb19a..d4bc69a30093 100644 --- a/content/admin/troubleshooting-your-instance/index.md +++ b/content/admin/troubleshooting-your-instance/index.md @@ -4,6 +4,7 @@ intro: 'Diagnose and resolve common problems with {% data variables.location.pro versions: ghes: '*' children: + - /troubleshooting-upgrades-and-migrations - /troubleshooting-storage-and-disks - /troubleshooting-github-actions-data-and-database-health shortTitle: Troubleshoot your instance diff --git a/content/admin/troubleshooting-your-instance/troubleshooting-upgrades-and-migrations/index.md b/content/admin/troubleshooting-your-instance/troubleshooting-upgrades-and-migrations/index.md new file mode 100644 index 000000000000..8d6971782172 --- /dev/null +++ b/content/admin/troubleshooting-your-instance/troubleshooting-upgrades-and-migrations/index.md @@ -0,0 +1,9 @@ +--- +title: Troubleshooting upgrades and migrations +intro: 'Resolve problems that occur during or after an upgrade to {% data variables.location.product_location %}.' +versions: + ghes: '*' +children: + - /pending-reboot-after-a-hotpatch +shortTitle: Upgrades and migrations +--- diff --git a/content/admin/troubleshooting-your-instance/troubleshooting-upgrades-and-migrations/pending-reboot-after-a-hotpatch.md b/content/admin/troubleshooting-your-instance/troubleshooting-upgrades-and-migrations/pending-reboot-after-a-hotpatch.md new file mode 100644 index 000000000000..9ffb34f523e0 --- /dev/null +++ b/content/admin/troubleshooting-your-instance/troubleshooting-upgrades-and-migrations/pending-reboot-after-a-hotpatch.md @@ -0,0 +1,83 @@ +--- +title: Pending reboot after a hotpatch +intro: 'A hotpatch can install updates that only take effect after a restart. Until {% data variables.location.product_location %} reboots, it keeps running the old versions, which can cause unpredictable problems.' +versions: + ghes: '*' +shortTitle: Pending reboot +contentType: how-tos +category: + - Troubleshoot your instance +--- + +## Symptoms + +After you install a hotpatch, you may see problems that seem unrelated to the upgrade. + +* Features that worked before the hotpatch start failing. +* The instance is unstable in ways that are inconsistent and hard to reproduce. +* Services behave unexpectedly, or do not pick up a change you have made. + +Nothing in these symptoms points back to the upgrade, so a pending reboot is worth ruling out before you investigate further. + +## Causes + +A hotpatch can include updates to the kernel or to core system packages. The running system continues to use the versions that were loaded when it last started, so those updates do not take effect until you restart. + +The hotpatch upgrade script tells you when a reboot is required, but it does not restart the instance for you. If you miss that message, or defer the reboot and then forget it, the instance runs in a mixed state where some components are updated and others are not. Installing further hotpatches without rebooting compounds this. + +## Confirming the problem + +1. SSH into the administrative shell. For more information, see [AUTOTITLE](/admin/administering-your-instance/administering-your-instance-from-the-command-line/accessing-the-administrative-shell-ssh). +1. Check whether a reboot is outstanding. Either file is present only when the system requires a restart. + + ```shell + ls /var/run/reboot-required /var/run/reboot-required.pkgs + ``` + + If either file is listed, a reboot is outstanding. If neither exists, the command reports `No such file or directory` for both paths, which means no reboot is pending and the problem lies elsewhere. + +1. If `/var/run/reboot-required.pkgs` is present, you can see which packages are waiting for the restart. + + ```shell + cat /var/run/reboot-required.pkgs + ``` + +## Resolving the problem + +Rebooting makes {% data variables.location.product_location %} unavailable, so plan it rather than doing it immediately. + +> [!WARNING] +> Rebooting interrupts anyone using the instance. Enabling maintenance mode stops new work from starting, but it does not stop work that is already running, so wait for active processes to finish before you reboot. + +1. Schedule a maintenance window with your users. +1. Enable maintenance mode, then wait for all active processes to complete. For more information, see [AUTOTITLE](/admin/administering-your-instance/configuring-maintenance-mode/enabling-and-scheduling-maintenance-mode). +1. Reboot the instance. + + ```shell + sudo reboot + ``` + +1. When the instance is back, confirm that no reboot is still pending. Both files should now be gone, so the command reports `No such file or directory` for each path. That is the result you want. + + ```shell + ls /var/run/reboot-required /var/run/reboot-required.pkgs + ``` + +1. Disable maintenance mode and confirm that the original problem is resolved. + +## Preventing recurrence + +* When a hotpatch reports that a reboot is required, schedule it and track it to completion. You can pick a convenient time, but reboot as soon as practical, particularly where the hotpatch included security fixes. For more information, see [AUTOTITLE](/admin/upgrading-your-instance/performing-an-upgrade/upgrading-with-a-hotpatch). +* Do not install several hotpatches in a row without rebooting when one is required, because the instance drifts further from the state the updates expect. +* Check for a pending reboot as part of your post-upgrade checks, so you catch it before your users do. + +## Contacting {% data variables.contact.github_support %} + +If the problems continue after you reboot, or you are unsure about any of these steps, contact {% data variables.contact.github_support %} rather than continuing. For more information, see [AUTOTITLE](/support/contacting-github-support/creating-a-support-ticket). + +If you have already opened a ticket, attaching a support bundle helps {% data variables.contact.github_support %} diagnose the problem faster. For more information, see [AUTOTITLE](/support/contacting-github-support/providing-data-to-github-support). + +## Further reading + +* [AUTOTITLE](/admin/upgrading-your-instance/preparing-to-upgrade/overview-of-the-upgrade-process) +* [AUTOTITLE](/admin/administering-your-instance/administering-your-instance-from-the-command-line/command-line-utilities) diff --git a/content/authentication/keeping-your-account-and-data-secure/preventing-unauthorized-access.md b/content/authentication/keeping-your-account-and-data-secure/preventing-unauthorized-access.md index b14bc45c6ef7..332c9faa03fa 100644 --- a/content/authentication/keeping-your-account-and-data-secure/preventing-unauthorized-access.md +++ b/content/authentication/keeping-your-account-and-data-secure/preventing-unauthorized-access.md @@ -45,4 +45,13 @@ If you see restrictions on your account, complete the following steps to secure 1. Check your inbox (and spam folder) for security emails from {% data variables.product.github %} and follow any instructions. If restrictions remain after you secure your account, contact {% data variables.contact.github_support %}. + +#### If an attacker changed your sign-in settings + +If you own a personal account and can't sign in because an attacker changed your password, email address, or two-factor authentication settings, complete the following steps. If you lost access to your own two-factor authentication credentials, see [AUTOTITLE](/authentication/securing-your-account-with-two-factor-authentication-2fa/recovering-your-account-if-you-lose-your-2fa-credentials). + +1. Secure the email account associated with {% data variables.product.github %} and make sure you can access it. +1. Contact {% data variables.contact.github_support %}. + +During its review, {% data variables.contact.github_support %} may temporarily suspend your account. {% data variables.contact.github_support %} may remove authentication settings changed by the attacker and send you a password-reset link that expires after 24 hours. After you regain access, complete the steps at the beginning of this article to secure your account. {% endif %} diff --git a/content/code-security/concepts/secret-security/push-protection-and-the-github-mcp-server.md b/content/code-security/concepts/secret-security/push-protection-and-the-github-mcp-server.md index 2381b5efd19c..75e77a17ad6a 100644 --- a/content/code-security/concepts/secret-security/push-protection-and-the-github-mcp-server.md +++ b/content/code-security/concepts/secret-security/push-protection-and-the-github-mcp-server.md @@ -33,5 +33,5 @@ To resolve the block, you can either: ## Further reading * [AUTOTITLE](/code-security/concepts/secret-security/push-protection) -* [About the {% data variables.product.github %} MCP server](/copilot/concepts/context/mcp#about-the-github-mcp-server) +* [About the {% data variables.product.github %} MCP server](/copilot/concepts/customizations/mcp#about-the-github-mcp-server) * [AUTOTITLE](/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server) diff --git a/content/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/protecting-endpoints-with-package-firewall.md b/content/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/protecting-endpoints-with-package-firewall.md index c21a4a5a2374..70f085b04542 100644 --- a/content/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/protecting-endpoints-with-package-firewall.md +++ b/content/code-security/how-tos/secure-your-supply-chain/secure-your-dependencies/protecting-endpoints-with-package-firewall.md @@ -69,17 +69,17 @@ Use your user-level `.npmrc` file to configure npm. In the examples, replace `EN 1. Add the following configuration to your user-level `.npmrc` file: ```text - registry=https://package-firewall.github.com/npm/enterprises/ENTERPRISE - //package-firewall.github.com/npm/enterprises/ENTERPRISE/:_authToken=${GITHUB_TOKEN} + registry=https://package-firewall.githubapp.com/npm/enterprises/ENTERPRISE + //package-firewall.githubapp.com/npm/enterprises/ENTERPRISE/:_authToken=${GITHUB_TOKEN} ``` Alternatively, configure the same settings from the command line: ```shell npm config set registry \ - https://package-firewall.github.com/npm/enterprises/ENTERPRISE + https://package-firewall.githubapp.com/npm/enterprises/ENTERPRISE npm config set \ - '//package-firewall.github.com/npm/enterprises/ENTERPRISE/:_authToken=${GITHUB_TOKEN}' + '//package-firewall.githubapp.com/npm/enterprises/ENTERPRISE/:_authToken=${GITHUB_TOKEN}' ``` ### Configuring Artifactory @@ -94,7 +94,7 @@ You must have administrator privileges in your Artifactory instance. 1. In Artifactory, click the **Administration** tab, then click **Create a repository**. 1. Select **Remote** as the repository type, then select **npm** as the package type. 1. In the "Repository key" field, type a name such as `gh-package-firewall`. -1. In the "URL" field, type `https://package-firewall.github.com/npm/enterprises/ENTERPRISE`, replacing `ENTERPRISE` with your enterprise slug. +1. In the "URL" field, type `https://package-firewall.githubapp.com/npm/enterprises/ENTERPRISE`, replacing `ENTERPRISE` with your enterprise slug. 1. In the "Password / Access Token" field, paste a valid {% data variables.product.pat_generic %}, then select **Enable Token Authentication**. 1. Select the **Stage** where you want to use the firewall, based on your Artifactory configuration. 1. In the "Pattern" field, type `**/*` to include all package paths. diff --git a/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md b/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md index 0894559b7d37..87901fccdeec 100644 --- a/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md +++ b/content/code-security/how-tos/use-ghas-with-ai-coding-agents/scan-for-secrets-with-github-mcp-server.md @@ -143,6 +143,6 @@ If push protection is enabled, the MCP server also blocks secrets from being inc |---|---| | Scanning returns no results | Verify the `secret_protection` toolset is enabled in your MCP configuration. | | Repository not eligible |{% data variables.product.prodname_secret_scanning_caps %} via MCP is available to public repositories and requires {% data variables.product.prodname_GH_secret_protection %} to be enabled for private and internal repositories. | -| Agent doesn't recognize the tool | Confirm your IDE or agent supports MCP. See [AUTOTITLE](/copilot/concepts/context/mcp#availability). | +| Agent doesn't recognize the tool | Confirm your IDE or agent supports MCP. See [AUTOTITLE](/copilot/concepts/customizations/mcp#where-you-can-use-mcp). | | Unexpected detection results | Your organization's security configuration controls which patterns are scanned. Check your repository security settings. | | Tool works in one client but not another | The experience varies across MCP-compatible clients. Check your client's MCP documentation for supported features. | diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-analyze.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-analyze.md index 556098c0b464..afac393138d5 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-analyze.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-analyze.md @@ -260,7 +260,7 @@ Download any missing queries before analyzing. ### Options to control the model packs to be used -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-interpret-results.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-interpret-results.md index dcd9a4be50f3..639231db2e7e 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-interpret-results.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-interpret-results.md @@ -261,7 +261,7 @@ This overrides the GITHUB\_TOKEN environment variable. ### Options to specify which extensions to use when interpreting the results -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-run-queries.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-run-queries.md index 782f5dae7776..2695431ff806 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-run-queries.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/database-run-queries.md @@ -102,7 +102,7 @@ during database creation from a Code Scanning configuration file. ### Options to control the model packs to be used -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/execute-queries.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/execute-queries.md index 675e408857ea..4995d19d562a 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/execute-queries.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/execute-queries.md @@ -85,7 +85,7 @@ stored in the output location. ### Options to control the model packs to be used -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/generate-overlay-changes.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/generate-overlay-changes.md index 10880b7de458..970769ae340b 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/generate-overlay-changes.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/generate-overlay-changes.md @@ -1,7 +1,9 @@ --- title: generate overlay-changes -intro: | +intro: |- [Plumbing] Generate a file that can be used for the + --overlay-changes option to + codeql database create when extracting an overlay database. versions: # DO NOT MANUALLY EDIT. CHANGES WILL BE OVERWRITTEN BY A 🤖 fpt: '*' ghec: '*' diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/query-run.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/query-run.md index 21d85e84c84a..ca8c7149a144 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/query-run.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/query-run.md @@ -360,7 +360,7 @@ This overrides the GITHUB\_TOKEN environment variable. ### Options to control the extension packs -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions-by-pack.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions-by-pack.md index 3008995e0feb..e43694913751 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions-by-pack.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions-by-pack.md @@ -87,7 +87,7 @@ value. (Note: On Windows the path separator is `;`). -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions.md b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions.md index e83a4fa90d40..92b1eb140c51 100644 --- a/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions.md +++ b/content/code-security/reference/code-scanning/codeql/codeql-cli-manual/resolve-extensions.md @@ -105,7 +105,7 @@ value. (Note: On Windows the path separator is `;`). -#### `--model-packs=<`>... +#### `--model-packs=...` A list of CodeQL pack names, each with an optional version range, to be used as model packs to customize the queries that are about to be diff --git a/content/copilot/concepts/agent-capabilities/about-agents/agent-apps.md b/content/copilot/concepts/agent-capabilities/about-agents/agent-apps.md index f1dba2fb4d4d..621d9304d8f1 100644 --- a/content/copilot/concepts/agent-capabilities/about-agents/agent-apps.md +++ b/content/copilot/concepts/agent-capabilities/about-agents/agent-apps.md @@ -29,7 +29,7 @@ You can use these entry points in the same way as you use {% data variables.copi ## How {% data variables.copilot.agent_apps %} work -An {% data variables.copilot.agent_app %} is a {% data variables.product.prodname_github_app %} that a partner has configured to act as an agent. Each {% data variables.copilot.agent_app %} can define a custom agent with its own prompt, model, tools, and Model Context Protocol (MCP) servers. To learn more about custom agents and MCP, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents) and [AUTOTITLE](/copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent). +An {% data variables.copilot.agent_app %} is a {% data variables.product.prodname_github_app %} that a partner has configured to act as an agent. Each {% data variables.copilot.agent_app %} can define a custom agent with its own prompt, model, tools, and Model Context Protocol (MCP) servers. To learn more about custom agents and MCP, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents) and [AUTOTITLE](/copilot/concepts/customizations/mcp). {% data variables.copilot.agent_apps_caps %} can connect to the partner's own systems through MCP servers. These MCP servers authorize the {% data variables.copilot.agent_app %} using a JWT assertion issued by {% data variables.product.github %}, so the partner can securely identify your account and their {% data variables.copilot.agent_app %} without you managing additional credentials. diff --git a/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/agent-management.md b/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/agent-management.md index c49001a4e071..bc89b6f5b96e 100644 --- a/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/agent-management.md +++ b/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/agent-management.md @@ -26,7 +26,7 @@ Alongside {% data variables.product.prodname_copilot_short %}, you can use {% da {% data variables.product.company_short %} partners can also offer their own agents as {% data variables.copilot.agent_apps %}, which you install as {% data variables.product.prodname_github_apps %} and trigger from issues, pull requests, and the Agents UI. See [AUTOTITLE](/copilot/concepts/agent-capabilities/about-agents/agent-apps). -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/cloud-agent/about-custom-agents). +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/customizations/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). diff --git a/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/getting-a-second-opinion.md b/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/getting-a-second-opinion.md index 2c9c7c21b0d8..afbc78f7a34d 100644 --- a/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/getting-a-second-opinion.md +++ b/content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/getting-a-second-opinion.md @@ -116,4 +116,4 @@ When {% data variables.product.prodname_copilot_short %} consults the rubber duc ## Further reading -* [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents#built-in-agents) +* [AUTOTITLE](/copilot/concepts/customizations/custom-agents#built-in-agents) diff --git a/content/copilot/concepts/agent-capabilities/index.md b/content/copilot/concepts/agent-capabilities/index.md index 4377cc289390..7fb00b005fed 100644 --- a/content/copilot/concepts/agent-capabilities/index.md +++ b/content/copilot/concepts/agent-capabilities/index.md @@ -4,6 +4,7 @@ intro: Understand what {% data variables.product.prodname_copilot %} agents can versions: feature: copilot redirect_from: + - /copilot/concepts/agents - /copilot/concepts/tools children: - /about-agents diff --git a/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md b/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md deleted file mode 100644 index fee09e1be425..000000000000 --- a/content/copilot/concepts/agents/cloud-agent/about-custom-agents.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: About custom agents -shortTitle: Custom agents -intro: '{% data variables.copilot.custom_agents_caps_short %} enhance {% data variables.product.prodname_copilot_short %} with assistance tailored to your needs.' -versions: - feature: copilot -category: - - Learn about Copilot -contentType: concepts -redirect_from: - - /copilot/concepts/agents/coding-agent/about-custom-agents ---- - -{% data reusables.copilot.copilot-cli.custom-agents-about-intro %} - -{% data reusables.copilot.copilot-cli.custom-agents-about-details %} - -## Where you can use {% data variables.copilot.custom_agents_short %} - -{% data reusables.copilot.custom-agents-ide-preview %} - -Once you create {% data variables.copilot.custom_agents_short %}, they become available to: - -* **{% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}**: The agents tab and panel, issue assignment, and pull requests -* **{% data variables.copilot.copilot_cloud_agent %} in IDEs**: {% data variables.product.prodname_vscode %}, JetBrains IDEs, Eclipse, and Xcode -* **The {% data variables.copilot.github_copilot_app %}** -* **{% data variables.copilot.copilot_cli %}** - -You can use {% data variables.copilot.agent_profiles %} directly in {% data variables.product.prodname_vscode %}, JetBrains IDEs, Eclipse, and Xcode. Some properties may function differently or be ignored between environments. - -For more information on using {% data variables.copilot.custom_agents_short %} in {% data variables.product.prodname_vscode %}, see [{% data variables.copilot.custom_agents_caps_short %} in {% data variables.product.prodname_vscode_shortname %}](https://code.visualstudio.com/docs/copilot/customization/custom-agents). - -## Next steps - -To create your own {% data variables.copilot.custom_agents_short %}, see: - -* [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents) -* [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli) -* [AUTOTITLE](/copilot/reference/customization-cheat-sheet) diff --git a/content/copilot/concepts/agents/cloud-agent/index.md b/content/copilot/concepts/agents/cloud-agent/index.md deleted file mode 100644 index bef608f18120..000000000000 --- a/content/copilot/concepts/agents/cloud-agent/index.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Concepts for GitHub Copilot cloud agent -shortTitle: '{% data variables.copilot.copilot_cloud_agent_short_cap_c %}' -allowTitleToDifferFromFilename: true -intro: Learn how {% data variables.copilot.copilot_cloud_agent %} can carry out research, planning and coding tasks for you, working independently in the same workflow you use yourself. -versions: - feature: copilot -children: - - /about-custom-agents - - /mcp-and-cloud-agent -contentType: concepts -redirect_from: - - /copilot/concepts/agents/coding-agent - - /copilot/concepts/coding-agent ---- - -These articles provide an overview of {% data variables.copilot.copilot_cloud_agent %}. For instructions on configuring and using {% data variables.copilot.copilot_cloud_agent %}, see the how-to articles under [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent). diff --git a/content/copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent.md b/content/copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent.md deleted file mode 100644 index 2cbacb073fcb..000000000000 --- a/content/copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Model Context Protocol (MCP) and GitHub Copilot cloud agent -shortTitle: MCP and {% data variables.copilot.copilot_cloud_agent_short %} -allowTitleToDifferFromFilename: true -intro: Find out about using the Model Context Protocol (MCP) with {% data variables.copilot.copilot_cloud_agent %}. -versions: - feature: copilot -contentType: concepts -redirect_from: - - /copilot/concepts/agents/coding-agent/mcp-and-coding-agent - - /copilot/concepts/coding-agent/mcp-and-coding-agent -category: - - Integrate Copilot with your tools ---- - -## Overview - -{% data reusables.copilot.cloud-agent.mcp-brief-intro %} - -The agent can use tools provided by local and remote MCP servers. Some MCP servers are configured by default to provide the best experience for getting started. - -For more information on MCP, see [the official MCP documentation](https://modelcontextprotocol.io/introduction). For information on some of the currently available MCP servers, see [the MCP servers repository](https://github.com/modelcontextprotocol/servers/tree/main). - -{% data reusables.copilot.mcp.repo-mcp-limitations %} - -## Default MCP servers - -The following MCP servers are configured automatically for {% data variables.copilot.copilot_cloud_agent %}: - -* **{% data variables.product.github %}**: The {% data variables.product.github %} MCP server gives {% data variables.product.prodname_copilot_short %} access to {% data variables.product.github %} data like issues and pull requests. To learn more, see [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/copilot-for-common-tasks/use-the-github-mcp-server). - * By default, the {% data variables.product.github %} MCP server connects to {% data variables.product.github %} using a specially scoped token that only has read-only access to the current repository. You can customize it to use a different token with broader access. For more details, see [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers#customizing-the-built-in-github-mcp-server). - -* **Playwright**: The [Playwright MCP server](https://github.com/microsoft/playwright-mcp) gives {% data variables.product.prodname_copilot_short %} access to web pages, including the ability to read, interact and take screenshots. - * By default, the Playwright MCP server is only able to access web resources hosted within {% data variables.product.prodname_copilot_short %}'s own environment, accessible on `localhost` or `127.0.0.1`. - -## Setting up MCP servers in a repository - -Repository administrators can configure MCP servers for use within that repository. This is done via a JSON-formatted configuration in repository settings on {% data variables.product.github %}. - -> [!NOTE] -> Repository MCP configuration on {% data variables.product.github %} applies to both {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %}. MCP servers configured in repository MCP settings are available to both agents. - -Once MCP servers are configured for use within a repository, the tools specified in the configuration will be available to {% data variables.copilot.copilot_cloud_agent %} during each assigned task. - -{% data variables.product.prodname_copilot_short %} will use available tools autonomously, and will not ask for approval before use. - -For details of how to set up MCP servers in a repository, see [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers). - -## MCP servers for {% data variables.copilot.custom_agents_short %} - -You can also configure MCP servers for {% data variables.copilot.custom_agents_short %}. - -MCP servers configured in {% data variables.copilot.custom_agents_short %} are available only to that specific agent and follow the same processing order as other MCP configurations, with {% data variables.copilot.copilot_custom_agent_short %} MCP settings processed after default servers but before repository-level configurations. - -For more information on configuring MCP servers for {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/reference/custom-agents-configuration#mcp-server-configuration-details). - -## Best practices - -* Enabling third-party MCP servers for use may impact the performance of the agent and the quality of the outputs. Review the third-party MCP server thoroughly and ensure that it meets your organization’s requirements. - -* By default, {% data variables.copilot.copilot_cloud_agent %} does not have access to write MCP server tools. However, some MCP servers do contain such tools. Be sure to review the tools available in the MCP server you want to use. Update the `tools` field in the MCP configuration with only the necessary tooling. - -* Carefully review the configured MCP servers prior to saving the configuration to ensure the correct servers are configured for use. diff --git a/content/copilot/concepts/agents/copilot-cli/about-cli-extensions.md b/content/copilot/concepts/agents/copilot-cli/about-cli-extensions.md deleted file mode 100644 index 03eb95a39b08..000000000000 --- a/content/copilot/concepts/agents/copilot-cli/about-cli-extensions.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: About extensions for {% data variables.copilot.copilot_cli %} -shortTitle: CLI extensions -allowTitleToDifferFromFilename: true -intro: 'Extensions let you add your own tools and slash commands to {% data variables.copilot.copilot_cli %}, using only the SDK that ships with the CLI.' -product: '{% data reusables.gated-features.copilot-cli %}' -versions: - feature: copilot -contentType: concepts -category: - - Learn about Copilot # Copilot discovery page - - Learn about Copilot CLI # Copilot CLI bespoke page -docsTeamMetrics: - - copilot-cli ---- - -{% data reusables.copilot.copilot-cli.cli-extensions-experimental %} - -An extension lets you add your own capabilities to {% data variables.copilot.copilot_cli_short %}. Each extension is a small Node.js module that runs as a separate process alongside your interactive session and connects back to it. Through that connection an extension can add: - -* **Tools** that {% data variables.product.prodname_copilot_short %} can call while it works on your behalf. -* **Slash commands** that you run yourself. - -Because an extension runs real code on your machine, you can add capabilities the built-in tools don't have. For example, an extension can watch what happens in a session and keep a running total across tool calls, which a one-off shell command can't do. - -This article explains how extensions work and how {% data variables.copilot.copilot_cli_short %} handles them. For a hands-on guide to building your own extensions, see [AUTOTITLE](/copilot/tutorials/create-an-extension). - -> [!WARNING] -> Extensions execute on your computer with your privileges. Only load extension code that you trust, in the same way you would only run any other script you didn't write yourself. - -## How extensions are discovered - -When {% data variables.copilot.copilot_cli_short %} starts, it looks for extensions in several locations. Each extension lives in its own subdirectory, and that subdirectory must contain an entry file named `extension.mjs`, `extension.cjs`, or `extension.js`. These are all JavaScript files: the {% data variables.copilot.copilot_cli_short %} runs the entry file directly with Node.js, so an extension must be written in JavaScript—TypeScript and other languages are currently not supported. - -The name of the subdirectory becomes the name of the extension. - -| Source | Location | Availability | -| --- | --- | --- | -| **Project** | `.github/extensions/NAME/` in the current repository | Available to anyone working in that repository. | -| **User** | `~/.copilot/extensions/NAME/` | Available in all your CLI sessions, in every directory. | -| **Plugin** | An installed plugin | Available wherever the plugin is enabled. | - -## Choosing where an extension lives - -Where you put the extension directory determines who can use it: - -* Put it in **`.github/extensions/`** in a repository when the extension is specific to that project and you want to share it with everyone who works there. -* Put it in **`~/.copilot/extensions/`** when you want the extension available in all of your own sessions, regardless of which directory you start the CLI in. - -The two locations follow exactly the same structure—a named subdirectory containing an `extension.mjs` file—so you can move an extension from one to the other simply by relocating its folder. - -## Enabling extensions - -Extensions are currently an experimental feature, so you need to turn on experimental features. You can do this by doing either of the following: - -* Start the CLI with the `‑‑experimental` flag. -* Run the `/experimental on` slash command inside an interactive session. - -## Changing how the CLI handles extensions - -You can limit {% data variables.product.prodname_copilot_short %}'s access to extensions, or turn them off entirely, by using the `/extensions mode` command. When you use this command you get three options: - -* **Load & Augment** (the default)—the CLI runs your extensions, _and_ {% data variables.product.prodname_copilot_short %} can manage them. -* **Load Only**—the CLI runs your extensions, but {% data variables.product.prodname_copilot_short %} cannot manage them. -* **Disabled**—extensions are turned off entirely in the current session and will remain disabled in future sessions until you switch to one of the other two settings. Other current sessions are not affected. - -Any change you make takes effect immediately in the current session: - -* Switching **to Disabled** stops any extensions that are currently running. Their processes are shut down and their tools are no longer available. -* Switching **from Disabled** to either of the other settings starts your extensions. -* Switching between **Load Only** and **Load & Augment** just changes whether {% data variables.product.prodname_copilot_short %} can manage your extensions. - -### What "managing extensions" means - -In **Load & Augment** mode, {% data variables.product.prodname_copilot_short %} is given a small set of extra tools that let it work on the extension system directly, as part of carrying out your requests. Using these tools, {% data variables.product.prodname_copilot_short %} can: - -* **List** the extensions it has discovered and see their status. -* **Inspect** an extension, including a tail of its log file, to help diagnose one that has failed or is misbehaving. -* **Scaffold** a new extension—generate a starter `extension.mjs` file for you to build on. -* **Reload** extensions, so that code it (or you) has just written takes effect without restarting the session. - -This is what makes it possible for you to ask {% data variables.product.prodname_copilot_short %} to build an extension for you. {% data variables.product.prodname_copilot_short %} can create the file, write the code, and reload it, all without leaving the session. - -Choose **Load Only** when you want to keep a known, trusted set of extensions running but don't want {% data variables.product.prodname_copilot_short %} creating, reloading, or otherwise changing extension code—which runs on your machine—as a side effect of its work. Your existing extensions still run, and {% data variables.product.prodname_copilot_short %} can still call the tools they provide; it simply can't manage the extensions themselves. - -## Extensions compared with plugins - -Both extensions and plugins add functionality to {% data variables.copilot.copilot_cli_short %}, but they serve different purposes: - -* An **extension** is a single JavaScript module that you write to add tools and slash commands, backed by code that runs in your session. -* A **plugin** is an installable package that bundles reusable components—such as agents, skills, hooks, and integrations—and can be distributed through a marketplace. - -For more information about plugins, see [AUTOTITLE](/copilot/concepts/agents/about-plugins). - -## Further reading - -* [AUTOTITLE](/copilot/tutorials/create-an-extension) -* [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference#slash-commands-in-the-interactive-interface) -* [AUTOTITLE](/copilot/how-tos/copilot-cli) diff --git a/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md b/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md deleted file mode 100644 index 0d8becfc02d9..000000000000 --- a/content/copilot/concepts/agents/copilot-cli/about-custom-agents.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: About custom agents -shortTitle: Custom agents -intro: '{% data variables.copilot.custom_agents_caps_short %} enhance {% data variables.product.prodname_copilot_short %} with assistance tailored to your needs.' -versions: - feature: copilot -category: - - Learn about Copilot -contentType: concepts -docsTeamMetrics: - - copilot-cli ---- - -{% data reusables.copilot.copilot-cli.custom-agents-about-intro %} - -In addition to any {% data variables.copilot.custom_agents_short %} you define yourself, {% data variables.product.prodname_copilot_short %} includes a set of pre-built {% data variables.copilot.custom_agents_short %}. See [Built-in agents](#built-in-agents). - -{% data reusables.copilot.copilot-cli.custom-agents-about-details %} - -## Built-in agents - -In addition to the main {% data variables.product.prodname_copilot_short %} agent, which processes your request when you submit a prompt, {% data variables.copilot.copilot_cli_short %} includes the following built-in agents which the main agent can run as subagents to assist with common development tasks. These agents are optimized for efficiency and accuracy, leveraging the capabilities of the underlying language models and tools to provide high-quality assistance in their respective domains. - -{% data variables.product.prodname_copilot_short %} will automatically use an appropriate built-in agent based on your prompt and the current context. For example, the prompt `How does authentication work in this codebase?` will typically trigger the Explore agent, and using the `/research` slash command will trigger the Research agent. - -* **explore** — A fast, lightweight codebase exploration agent. It uses code intelligence, grep, glob, view, and shell tools to search files and understand code structure. It will not change any files, so can be called in parallel to other subagents being run by the main {% data variables.product.prodname_copilot_short %} agent. It has read-only access to GitHub MCP server tools. - -* **task** — A command execution agent that runs development commands (tests, builds, linters, formatters, dependency installs) and reports results efficiently. It returns a brief summary on success, and full output on failure, keeping the main context clean. It has access to all of the tools the parent agent can use (excluding some that are not appropriate in a subagent context), with the same permissions granted or denied. - -* **general-purpose** — This agent essentially has all of the same capabilities as the main {% data variables.product.prodname_copilot_short %} agent. The main agent can run the general-purpose agent as a subagent to assist with any task that requires a separate context window, or to run in parallel when appropriate. - -* **code-review** — Reviews code changes with an extremely high signal-to-noise ratio. This agent analyzes staged/unstaged changes and branch diffs, surfacing only issues that genuinely matter: bugs, security vulnerabilities, race conditions, memory leaks, and logic errors. It never comments on style or formatting. It will not make any changes to files. - -* **research** — This agent operates as a staff-level software engineer and research specialist. It provides exhaustive, meticulously researched answers about codebases, APIs, libraries, and software architecture. It uses {% data variables.product.github %} search/exploration tools, web fetch/search, and local tools. You can invoke it explicitly using the `/research` slash command. The main agent can also delegate research work to it when appropriate. - -* **rubber-duck** — A constructive critic that gives {% data variables.product.prodname_copilot_short %} a second opinion on its own plans, code, and tests. It runs on a different model from the one driving your session, so it brings a complementary perspective. It is designed to review proposed changes, not to make file changes itself. For more information, see [AUTOTITLE](/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/getting-a-second-opinion). - -* **security-review** — A read-only specialist that searches your codebase for exploitable security vulnerabilities and reports only high-confidence findings. You can invoke it explicitly using the `/security-review` slash command. The main agent can also delegate security-focused work to it, including when you explicitly ask it to find exploitable vulnerabilities. - -## Running agents as subagents - -One of the benefits of using custom agents you have defined yourself—or the built-in agents—is that the main {% data variables.product.prodname_copilot_short %} agent can run them as subagents with a separate context window. This means that your custom agent, or built-in agent, can focus on a specific subtask without cluttering the context window of the main agent. - -Where appropriate, tasks performed by subagents can be run in parallel, allowing the overall task to be completed more quickly. - -For more information, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/comparing-cli-features). - -## Next steps - -To create your own {% data variables.copilot.custom_agents_short %}, see: - -* [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli) -* [AUTOTITLE](/copilot/reference/customization-cheat-sheet) diff --git a/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md b/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md deleted file mode 100644 index c9fd744d9e7c..000000000000 --- a/content/copilot/concepts/agents/copilot-cli/comparing-cli-features.md +++ /dev/null @@ -1,420 +0,0 @@ ---- -title: Comparing GitHub Copilot CLI customization features -shortTitle: Comparing CLI features -intro: 'Find out about the various ways you can customize {% data variables.product.prodname_copilot_short %}: what they do, and when to use them.' -product: '{% data reusables.gated-features.copilot-cli %}' -versions: - feature: copilot -contentType: concepts -category: - - Learn about Copilot # Copilot discovery page - - Learn about Copilot CLI # Copilot CLI bespoke page -docsTeamMetrics: - - copilot-cli ---- - -## Introduction - -{% data variables.copilot.copilot_cli_short %} is a terminal-based AI agent that can answer questions, plan work, and complete tasks on your behalf. It’s designed to be highly extensible, and there are various ways in which you can customize its behavior and extend its capabilities. - -This article explains the difference between: - -* **Custom instructions** - - These tell {% data variables.product.prodname_copilot_short %} **how to behave** in general. For example, to ensure any code that {% data variables.product.prodname_copilot_short %} writes conforms to your coding standards. [Find out more](#custom-instructions). - -* **Skills** - - These tell {% data variables.product.prodname_copilot_short %} **how to handle a specific kind of task**. For example, to use a particular tool when working on a specific type of task. [Find out more](#skills). - -* **Tools** - - These **provide abilities**. For example, for finding and modifying files, or for interacting with parts of {% data variables.product.github %}. [Find out more](#tools). - -* **MCP servers** - - These **add collections of tools** that allow {% data variables.product.prodname_copilot_short %} to interact with external services. [Find out more](#mcp-servers). - -* **Hooks** - - These let you **run your own logic at specific lifecycle moments**. For example, you can run a specific script every time a CLI session starts or ends. [Find out more](#hooks). - -* **Subagents** - - These are **delegated agent processes**, tied to the main agent and used to perform specific tasks separately from the main agent process. They have their own context window, which can be populated without affecting the main agent's context. [Find out more](#subagents). - -* **Custom agents** - - These are **definitions of specialized abilities**, designed to perform specific tasks. The main CLI agent can delegate a task to a subagent, using a custom agent profile, to apply specialist knowledge and a particular approach to the task. For example, a custom agent might perform the role of a React reviewer, a docs writer, a security auditor, or a test generator. [Find out more](#custom-agents). - -* **Plugins** - - These are **packages** that can deliver preconfigured customizations such as skills, hooks, custom agents, and MCP servers. [Find out more](#plugins). - -## Custom instructions - -### What are custom instructions? - -**Custom instructions** are persistent guidance that the {% data variables.copilot.copilot_cli_short %} loads from instruction files at the start of a session. - -{% data variables.product.prodname_copilot_short %} will find and load instruction files from a number of default locations in the repository, such as `AGENTS.md` and `.github/copilot-instructions.md`, or from your home directory at `$HOME/.copilot/copilot-instructions.md`. - -You can use the `--no-custom-instructions` flag to avoid loading these instructions. - -### What problem do custom instructions solve? - -Custom instructions help you: -* Keep {% data variables.product.prodname_copilot_short %} aligned with your coding conventions and preferences. -* Apply team or organization standards consistently. -* Avoid having to include repetitive reminders to {% data variables.product.prodname_copilot_short %} in every prompt. - -### When should you use custom instructions? - -Use custom instructions for: - -* Style and quality rules - - Example: "Prefer small PRs, write tests, and avoid changing public APIs without discussion." - -* Repository conventions - - Example: "Use `pnpm`, keep changelog entries in `CHANGELOG.md`, run `pnpm test` before committing." - -* Communication preferences - - Example: “Explain tradeoffs briefly, then provide the recommended choice.” - -### When shouldn't you use custom instructions? - -Avoid or keep them minimal when: - -* You only want the behavior in one workflow (use a **skill** instead). -* Your instructions are so large/specific they distract {% data variables.product.prodname_copilot_short %} from the immediate task (prefer a **skill** or a **custom agent**). - -### Find out more about custom instructions - -See [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions). - -## Skills - -### What is a skill? - -A **skill** is, minimally, a Markdown file containing instructions that {% data variables.product.prodname_copilot_short %} can use to perform tasks in a specific context. The name and skill description allow {% data variables.product.prodname_copilot_short %} to determine whether it should use the skill for a given task. If it decides to use the skill, it will load the instructions and follow them to complete the task. - -Skills can optionally reference other files, stored within the skill directory. These can include scripts that {% data variables.product.prodname_copilot_short %} can run when the skill is used. - -### What problem does a skill solve? - -Skills help you: -* Standardize how {% data variables.product.prodname_copilot_short %} performs tasks in a specific context (for example, when performing a code review). -* Provide "just-in-time" instructions without permanently changing {% data variables.product.prodname_copilot_short %}'s behavior. -* Avoid overloading {% data variables.product.prodname_copilot_short %}'s context window with instructions that are not relevant to the current task. - -### How do you access skills? - -You can manually invoke a skill by using a slash command. For example, `/Markdown-Checker check README.md`. Use `/skills list` to list the available skills. - -{% data variables.copilot.copilot_cli_short %} automatically invokes skills when it detects one that is relevant to the current task. - -### When should you use a skill? - -Use a skill when you want: - -* A repeatable set of instructions or functionality to be available for a type of task. - - Example: a documentation skill that checks that user-facing documentation is updated when frontend code is changed. - -* A consistent output format. - - Example: a "release note draft" skill that ensures {% data variables.product.prodname_copilot_short %} uses a template to create a release note. - -* A workflow you sometimes need, but not always. - - Example: a “deep refactor” skill you only enable during migrations. - -### When shouldn't you use a skill? - -Avoid skills when: - -* The guidance should **apply to everything** you do (use **custom instructions** instead). -* You need new capabilities (you may need an **MCP server** to add tools, or a **custom agent** for specialization). - -### Find out more about agent skills - -See [AUTOTITLE](/copilot/concepts/agents/about-agent-skills). - -## Tools - -### What is a tool? - -A **tool** is an ability that {% data variables.product.prodname_copilot_short %} uses to get something done—like searching files, viewing file contents, editing, running a task, or invoking a skill. Some tools are built in, and others can be added through MCP servers. - -### What problem do tools solve? - -Tools let the CLI: - -* Gather accurate context (using read/search tools). -* Make changes safely (using edit tools). -* Execute commands and validate outcomes (potentially using subagents). - -### When should you use tools? - -You typically don't call tools directly—{% data variables.product.prodname_copilot_short %} decides to use tools as needed. You can allow or deny use of tools, either for a specific task, for the current session, or for all of your {% data variables.copilot.copilot_cli_short %} sessions. - -You’ll see {% data variables.product.prodname_copilot_short %} using tools when you: - -* Ask {% data variables.product.prodname_copilot_short %} to search the repository for something, update a file, or run tests. -* Invoke a skill—which triggers the `skill` tool. -* Ask {% data variables.product.prodname_copilot_short %} to perform a task that requires it to use a tool supplied by an MCP server. -* Task {% data variables.product.prodname_copilot_short %} to complete a complex task and it decides to delegate to a subagent—which triggers the `task` tool. - -### Find out more about allowing or denying tools - -See [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-cli#allowed-tools). - -## MCP servers - -### What is an MCP server? - -An **MCP server** is a service that allows AI applications, such as {% data variables.copilot.copilot_cli_short %}, to connect to external data sources and tools. - -Adding an MCP server to {% data variables.copilot.copilot_cli_short %} provides additional capabilities, by allowing you to use tools supplied by that MCP server. For example, you could add an MCP server that provides tools for interacting with an online calendar application, or a support ticketing system. - -### What problem do MCP servers solve? - -MCP servers help when the built-in tools aren’t enough. They can: - -* Connect {% data variables.copilot.copilot_cli_short %} to external systems. -* Add purpose-built tools (for example, for working with APIs, databases, or image generation). -* Standardize safe access patterns for non-repository resources. - -### When should you use an MCP server? - -Use an MCP server when you need: - -* Integration with external data or systems. - - Example: `How many support tickets have been opened this month for Product X?` - -* Domain-specific actions that you want the CLI to perform on your behalf. - - Example: `Message the bug-watch channel: Only 2 support tickets raised this month for Product X.` - -### When shouldn't you use an MCP server? - -Avoid adding MCP servers when: - -* Built-in tools already cover your needs. - -### Find out more about MCP servers - -See [AUTOTITLE](/copilot/concepts/context/mcp). - -## Hooks - -### What is a hook? - -**Hooks** allow you to specify that, at a given point in a session lifecycle, {% data variables.copilot.copilot_cli_short %} will execute a shell command you have defined. - -| Hook | When it runs | -| ---- | ------------ | -| `preToolUse` / `postToolUse` | Before/after a tool runs. | -| `userPromptSubmitted` | When a user submits a prompt. | -| `sessionStart` / `sessionEnd` | At the start/end of a session. | -| `errorOccurred` | When an error occurs. | -| `agentStop` | When the main agent stops without an error. | -| `subagentStop` | When a subagent completes. | - -### What problem do hooks solve? - -Hooks help when you want **programmable control or observability** around {% data variables.copilot.copilot_cli_short %} behavior, such as: - -* **Enforcing guardrails**—block or warn before certain tools run. -* **Adding logging/telemetry** -* **Customizing retry/abort behavior on recoverable errors** -* **Adding "policy" checks**—for example, to prevent edits to protected paths. -* **Intercepting the moment a subagent finishes**—before results return to the parent agent. - -Hooks are useful when you need more control than skills or custom instructions can provide. While skills and instructions guide {% data variables.product.prodname_copilot_short %}'s behavior through prompts, hooks ensure that operations you have defined will be performed at specific moments—for example, to block a tool from running, or to log activity when a session ends. - -### When should you usehooks? - -Use hooks when you want: - -* **Tool guardrails** - - * Example: before `bash` runs, require that the specific command matches an allowlist. - * Example: before `edit` runs, block changes under `infra/` unless a ticket ID is present. - -* **Session lifecycle automation** - - * Example: when the agent stops, archive the transcript of the session to a storage location. - -* **Error handling policy** - - * Example: on rate limit errors, automatically choose "retry" with a capped retry count. - -* **Subagent workflow control** - - * Example: when a subagent finishes, validate its output before passing results back to the main agent. - -### When shouldn't you use hooks? - -Avoid hooks when: - -* You just need consistent prompting or workflow instructions (use **skills**). -* You want persistent preferences and standards (use **custom instructions**). -* You need new external capabilities (use **MCP servers** and tools). -* Maintaining configuration that can affect every session may be problematic for you. - -### Find out more about hooks - -See: -* [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/use-hooks) -* [AUTOTITLE](/copilot/reference/hooks-reference) - -## Subagents - -### What is a subagent? - -A **subagent** is the execution of a separate AI agent that the main agent of a {% data variables.copilot.copilot_cli_short %} session spins up to do a specific piece of work. - -{% data variables.copilot.copilot_cli_short %} uses a subagent when the main agent decides that delegating a chunk of work to a separate agent is the best way to complete the user’s request. - -### What problem do subagents solve? - -Subagents help {% data variables.product.prodname_copilot_short %}: - -* Keep the context window of the main agent in a CLI session focused, by offloading a chunk of work to a separate agent. -* Parallelize work, where necessary, by running certain tasks in the background. -* Run a custom agent separately from the main agent, performing specialist work with a different approach to the work carried out by the main agent. - -### When are subagents used? - -{% data variables.product.prodname_copilot_short %} is likely to use a subagent for: - -* Codebase exploration - - For example, listing all endpoints in an API. - -* Command execution for complex tasks - - For example, running a test suite, or building a large project and analyzing the results. - -* Reviewing changes - - For example, reviewing staged changes and identifying potential security issues. - -* Complex multi-step work - - For example, implementing a feature with several changes. - -* For using custom agents - - If you’ve defined a custom agent and it’s eligible for inference (`infer` is not set to `false`), {% data variables.product.prodname_copilot_short %} may choose to delegate work to that custom agent by spinning up a subagent with the custom agent's configuration. - -## Custom agents - -### What is a custom agent? - -**Custom agents** provide {% data variables.product.prodname_copilot_short %} with specialist knowledge about a particular subject, and define a particular approach that {% data variables.product.prodname_copilot_short %} should use when working in that area. You can think of a custom agent as a "persona" that {% data variables.product.prodname_copilot_short %} can adopt when working on certain tasks. - -{% data variables.copilot.copilot_cli_short %} has several built-in custom agents. For example, the `explore`, `task`, `research`, `code-review`, `rubber-duck`, and `general-purpose` agents. You can also define your own custom agents, to meet your specific needs. - -You define a custom agent in a Markdown file with YAML frontmatter. The file contains: - -* A description of the agent's role and expertise -* A list of allowed tools (or all tools) -* Optional MCP server connections -* An optional `infer` setting—when enabled, {% data variables.product.prodname_copilot_short %} will automatically delegate to this agent when it detects a task that matches the agent's specialty. - -### What problem do custom agents solve? - -Custom agents help when you need: - -* Specialist knowledge to be applied consistently in a particular context. -* Different tool permissions for different work, as defined in the custom agent configuration. -* To allow the main agent's context window to stay focused on the main task, with the custom agent's own context window being used for the specialist work it performs. - -### When should you use a custom agent? - -Use a custom agent when you want: - -* A specialized reviewer or helper - - Example: Create a "react-reviewer" custom agent that focuses on work involving React patterns. - -* Safer permissions - - Example: A custom agent that can only `view/grep/glob` (read-only) for auditing. - -* Optional auto-delegation - - Example: Set `infer: true` in the custom agent configuration so that {% data variables.product.prodname_copilot_short %} can automatically use this custom agent when appropriate. - -### When shouldn't you use a custom agent? - -Avoid custom agents when: - -* You only need guidance text (a **skill** can be a lighter-weight solution). -* You don't need specialization and the default agent performs tasks well. - -### Find out more about custom agents - -See [AUTOTITLE](/copilot/reference/custom-agents-configuration). - -## Plugins - -### What is a plugin? - -A **plugin** is an installable package that can deliver a bundle of functionality to {% data variables.product.prodname_copilot_short %}. A plugin can include any combination of the other customization features. For example, skills, custom agents, hooks, and MCP server configurations. - -{% data variables.product.prodname_copilot_short %} includes plugin management commands (install, update, list, uninstall) and supports installing from a marketplace or directly from a GitHub repository. - -### What problem do plugins solve? - -Plugins help you: - -* Easily add a bundle of functionality to {% data variables.product.prodname_copilot_short %} without having to manually configure each piece. -* Package and distribute a custom configuration—potentially a combination of skills, custom agents, hooks, and MCP servers—to your team, or to the public. -* Alter available functionality without having to manually copy files into directories. - -### When should you use a plugin? - -Use a plugin when: - -* You want a team-wide bundle - - Example: A company-wide engineering plugin that includes: - - * Skills for incident response. - * A custom agent for code review. - * An MCP server for internal services. - -* You want easy installation and updates - - Example: Install a plugin initially, then update it regularly using `/plugin update PLUGIN-NAME`. - -### When shouldn't you use a plugin? - -Avoid plugins when: - -* You're experimenting locally and don't need distribution (use local skills, custom instructions, or custom agents). -* You only need a small one-off workflow. A single skill file may be simpler. - -## Putting it together: choosing the right option - -| Requirement | Best option | -|---|---| -| I want {% data variables.product.prodname_copilot_short %} to always follow our repository conventions. | **Custom instructions** | -| I want a repeatable workflow I can invoke on demand. | **Skills** | -| I want {% data variables.product.prodname_copilot_short %} to answer questions and carry out work in my repository. | {% data variables.product.prodname_copilot_short %} requests permission to use the appropriate **tools** | -| I want guardrails, policy, or automation around tool use and session events. | **Hooks** | -| I need {% data variables.product.prodname_copilot_short %} to be able to use tools provided by an external service. | **MCP servers** | -| When working on particular tasks, I want {% data variables.product.prodname_copilot_short %} to operate as a specialist with a constrained toolset. | **Custom agent** | -| I want {% data variables.product.prodname_copilot_short %} to carry out a complex task on my behalf. | {% data variables.product.prodname_copilot_short %} automatically uses **subagents** when appropriate. | -| I want to add a package of functionality to {% data variables.copilot.copilot_cli_short %} without configuring it manually myself. | **Plugin** | - -## Further reading - -* [AUTOTITLE](/copilot/how-tos/copilot-cli) diff --git a/content/copilot/concepts/agents/copilot-cli/index.md b/content/copilot/concepts/agents/copilot-cli/index.md deleted file mode 100644 index 1de8c6e8053a..000000000000 --- a/content/copilot/concepts/agents/copilot-cli/index.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Concepts for GitHub Copilot CLI -shortTitle: '{% data variables.copilot.copilot_cli_short %}' -allowTitleToDifferFromFilename: true -intro: Learn how you can use {% data variables.product.prodname_copilot %} in your terminal. -versions: - feature: copilot -children: - - /comparing-cli-features - - /about-custom-agents - - /lsp-servers - - /about-cli-extensions -contentType: concepts -docsTeamMetrics: - - copilot-cli ---- diff --git a/content/copilot/concepts/agents/index.md b/content/copilot/concepts/agents/index.md deleted file mode 100644 index 1a2c501bd7a5..000000000000 --- a/content/copilot/concepts/agents/index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Concepts for GitHub Copilot agents -shortTitle: Agents -allowTitleToDifferFromFilename: true -intro: Learn how {% data variables.product.prodname_copilot %} can independently execute tasks across the software development lifecycle. -versions: - feature: copilot -children: - - /cloud-agent - - /copilot-cli - - /hooks - - /about-plugins - - /about-agent-skills -contentType: concepts ---- diff --git a/content/copilot/concepts/billing-and-usage/copilot-usage-metrics/copilot-metrics.md b/content/copilot/concepts/billing-and-usage/copilot-usage-metrics/copilot-metrics.md index 884c6d64b24f..1d9bd8b42604 100644 --- a/content/copilot/concepts/billing-and-usage/copilot-usage-metrics/copilot-metrics.md +++ b/content/copilot/concepts/billing-and-usage/copilot-usage-metrics/copilot-metrics.md @@ -29,10 +29,10 @@ category: Metrics are available through: -* The {% data variables.product.prodname_copilot_short %} usage metrics APIs, which provide detailed, exportable data at the enterprise, organization, repository, and user levels. -* The {% data variables.product.prodname_copilot_short %} usage metrics dashboard, which visualizes 28-day usage trends across your enterprise and organizations. -* The code generation dashboard, which breaks down how code is being generated by users and agents across your enterprise and organizations. -* The {% data variables.product.prodname_copilot_short %} impact dashboard, which groups users into adoption cohorts and connects that adoption to pull request output. +* The {% data variables.product.prodname_copilot_short %} usage metrics APIs, which provide detailed, exportable data at the enterprise, organization, repository, and user levels. See [AUTOTITLE](/rest/copilot/copilot-usage-metrics). +* The {% data variables.product.prodname_copilot_short %} usage metrics dashboard, which visualizes 28-day usage trends across your enterprise and organizations. See [AUTOTITLE](/copilot/how-tos/administer-copilot/view-usage-and-adoption). +* The code generation dashboard, which breaks down how code is being generated by users and agents across your enterprise and organizations. See [AUTOTITLE](/copilot/how-tos/administer-copilot/view-code-generation). +* The {% data variables.product.prodname_copilot_short %} impact dashboard, which groups users into adoption cohorts and connects that adoption to pull request output. See [AUTOTITLE](/copilot/how-tos/administer-copilot/view-impact-dashboard). * The {% data variables.product.prodname_copilot_short %} usage metrics NDJSON export, which offers raw data for custom BI tools or long-term storage. ## Which usage is included? diff --git a/content/copilot/concepts/context/index.md b/content/copilot/concepts/context/index.md deleted file mode 100644 index ddc99788ca85..000000000000 --- a/content/copilot/concepts/context/index.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Concepts for providing context to GitHub Copilot -shortTitle: Context -allowTitleToDifferFromFilename: true -intro: Extend the capabilities of {% data variables.product.prodname_copilot %} by providing additional context using Model Context Protocol. -versions: - feature: copilot -children: - - /mcp -contentType: concepts ---- diff --git a/content/copilot/concepts/copilot-surfaces/copilot-on-github.md b/content/copilot/concepts/copilot-surfaces/copilot-on-github.md index 1f96d7580a02..d501e6695c98 100644 --- a/content/copilot/concepts/copilot-surfaces/copilot-on-github.md +++ b/content/copilot/concepts/copilot-surfaces/copilot-on-github.md @@ -6,6 +6,9 @@ intro: 'Explore your repositories, plan changes, and delegate coding tasks to {% versions: feature: copilot redirect_from: + - /copilot/concepts/agents/cloud-agent + - /copilot/concepts/agents/coding-agent + - /copilot/concepts/coding-agent - /copilot/concepts/about-github-copilot-chat - /copilot/concepts/chat - /copilot/github-copilot-enterprise/copilot-chat-in-github/about-github-copilot-chat diff --git a/content/copilot/concepts/agents/about-agent-skills.md b/content/copilot/concepts/customizations/agent-skills.md similarity index 63% rename from content/copilot/concepts/agents/about-agent-skills.md rename to content/copilot/concepts/customizations/agent-skills.md index 3fdc99c4ab70..a3296b49ca13 100644 --- a/content/copilot/concepts/agents/about-agent-skills.md +++ b/content/copilot/concepts/customizations/agent-skills.md @@ -1,7 +1,7 @@ --- -title: About agent skills +title: Agent skills shortTitle: Agent skills -intro: Skills allow {% data variables.product.prodname_copilot_short %} to perform specialized tasks. +intro: 'Give {% data variables.product.prodname_copilot_short %} repeatable workflows with task-specific instructions, scripts, and resources.' product: '{% data reusables.gated-features.copilot-cloud-agent %}

{% data reusables.gated-features.copilot-cli %}
Sign up for {% data variables.product.prodname_copilot_short %} {% octicon "link-external" height:16 %}' versions: feature: copilot @@ -9,17 +9,31 @@ category: - Learn about Copilot - Learn about Copilot CLI contentType: concepts +redirect_from: + - /copilot/concepts/agents/about-agent-skills --- -> [!NOTE] -> Agent skills work with {% data variables.copilot.copilot_cloud_agent %}, {% data variables.copilot.copilot_code-review_short %}, the {% data variables.copilot.copilot_cli %}, the {% data variables.copilot.github_copilot_app %}, and agent mode in {% data variables.product.prodname_vscode %} and {% data variables.jetbrains.prodname_jetbrains_ides %}. - ## About agent skills Agent skills are folders of instructions, scripts, and resources that {% data variables.product.prodname_copilot_short %} can load when relevant to improve its performance in specialized tasks. The Agent Skills specification is an [open standard](https://github.com/agentskills/agentskills), used by a range of different AI systems. You can create your own skills to teach {% data variables.product.prodname_copilot_short %} to perform tasks in a specific, repeatable way—or use skills shared online, for example in the [`anthropics/skills`](https://github.com/anthropics/skills) repository or {% data variables.product.company_short %}'s community-created [`github/awesome-copilot`](https://github.com/github/awesome-copilot) collection. +For example, a skill for writing release notes can include your team's template, a script for gathering changes, and instructions for grouping them. The agent loads those resources when working on release notes, rather than including the whole workflow in every conversation. + +## Where you can use agent skills + +You can use agent skills with: + +* The {% data variables.copilot.github_copilot_app %}. +* {% data variables.copilot.copilot_cli %}. +* {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %} on {% data variables.product.prodname_dotcom_the_website %}. +* Agent mode in {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, and {% data variables.jetbrains.prodname_jetbrains_ides %}. + +IDE support depends on the version you use. See [AUTOTITLE](/copilot/reference/copilot-feature-matrix). + +## Finding and storing skills + You can also use `gh skill` in {% data variables.product.prodname_cli %} to discover and install skills from {% data variables.product.github %} repositories. For more information, see [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/add-skills#managing-skills-with-github-cli). {% data variables.product.prodname_copilot_short %} supports: @@ -27,6 +41,8 @@ You can also use `gh skill` in {% data variables.product.prodname_cli %} to disc * Project skills, stored in your repository (`.github/skills`, `.claude/skills`, or `.agents/skills`) * Personal skills, stored in your home directory and shared across projects (`~/.copilot/skills` or `~/.agents/skills`) +Supported locations depend on the surface. Use its setup guide to choose a location rather than assuming that a personal skill is available to an agent running in the cloud. + ## Next steps To create or add agent skills, see: diff --git a/content/copilot/concepts/customizations/comparing-customizations.md b/content/copilot/concepts/customizations/comparing-customizations.md new file mode 100644 index 000000000000..52420a32e49f --- /dev/null +++ b/content/copilot/concepts/customizations/comparing-customizations.md @@ -0,0 +1,398 @@ +--- +title: Comparing Copilot customization features +shortTitle: Comparing customizations +intro: 'Choose the right way to give {% data variables.product.prodname_copilot_short %} guidance, specialized expertise, and access to tools.' +versions: + feature: copilot +contentType: concepts +redirect_from: + - /copilot/concepts/agents/copilot-cli/comparing-cli-features +category: + - Learn about Copilot + - Learn about Copilot CLI +--- + +## Introduction + +You can customize {% data variables.product.prodname_copilot_short %} to follow your conventions, carry out repeatable workflows, or connect to systems beyond your codebase. + +This article explains the difference between: + +* **Custom instructions** + + These tell {% data variables.product.prodname_copilot_short %} **how to behave** in general. For example, to ensure code it writes follows your coding standards. [Find out more](#custom-instructions). + +* **Agent skills** + + These tell {% data variables.product.prodname_copilot_short %} **how to handle a specific kind of task**. For example, to follow your team's process when drafting release notes. [Find out more](#agent-skills). + +* **Tools** + + These **provide abilities**. For example, for finding and modifying files, or for interacting with parts of {% data variables.product.github %}. [Find out more](#tools). + +* **MCP servers** + + These **add collections of tools** that allow {% data variables.product.prodname_copilot_short %} to interact with external services. [Find out more](#mcp-servers). + +* **Hooks** + + These let you **run your own logic at specific points in an agent's workflow**. For example, you can run a script before the agent uses a tool. [Find out more](#hooks). + +* **Subagents** + + These **perform delegated work** separately from the main agent. They have their own conversation context, so their intermediate work does not fill the main agent's context window. [Find out more](#subagents). + +* **Custom agents** + + These **define specialized roles**, with instructions and tools for particular tasks. For example, a custom agent might act as a React reviewer, a docs writer, or a test generator. [Find out more](#custom-agents). + +* **Extensions** + + These **add capabilities implemented in code**. For example, a {% data variables.copilot.copilot_cli_short %} extension can add a tool that tracks session activity. [Find out more](#extensions). + +* **Plugins** + + These are **packages** that can deliver preconfigured customizations such as skills, hooks, custom agents, and MCP servers. [Find out more](#plugins). + +Support and configuration differ between surfaces. For a support comparison, see [AUTOTITLE](/copilot/reference/customization-cheat-sheet#ide-and-surface-support). + +## Custom instructions + +Custom instructions are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, {% data variables.copilot.copilot_code-review_short %}, {% data variables.copilot.copilot_chat_short %} on {% data variables.product.prodname_dotcom_the_website %}, and supported IDEs. The types of instructions available depend on where you use them. + +### What are custom instructions? + +Custom instructions are persistent guidance that {% data variables.product.prodname_copilot_short %} uses within a defined scope. For example, repository instructions can describe your project's coding conventions and test commands, while personal instructions can describe your communication preferences. + +Instructions guide the model, but do not guarantee that it will follow every rule. + +### What problem do custom instructions solve? + +Custom instructions help you: + +* Keep {% data variables.product.prodname_copilot_short %} aligned with your coding conventions and preferences. +* Apply team or organization standards consistently. +* Avoid including repetitive reminders in every prompt. + +### When should you use custom instructions? + +Use custom instructions for: + +* Style and quality rules. For example: "Prefer small pull requests, write tests, and avoid changing public APIs without discussion." +* Repository conventions. For example: "Use `pnpm`, keep changelog entries in `CHANGELOG.md`, and run `pnpm test` before committing." +* Communication preferences. For example: "Explain tradeoffs briefly, then provide the recommended choice." + +### When shouldn't you use custom instructions? + +Keep them minimal when: + +* You only want the behavior for one kind of task. Use a skill instead. +* The instructions are so detailed that they distract from the immediate task. Use a skill or a custom agent for specialized guidance. + +### Find out more about custom instructions + +* [AUTOTITLE](/copilot/concepts/prompting-and-context/custom-instructions) +* [AUTOTITLE](/copilot/reference/custom-instructions-support) + +## Agent skills + +Agent skills are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, {% data variables.copilot.copilot_code-review_short %}, and agent mode in {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, and {% data variables.jetbrains.prodname_jetbrains_ides %}. + +### What is a skill? + +A skill is a folder containing a `SKILL.md` file with instructions for a specific kind of task. Its name and description help {% data variables.product.prodname_copilot_short %} decide when to load those instructions. + +Skills can also include supporting resources, such as templates and scripts the agent can run. + +### What problem does a skill solve? + +Skills help you: + +* Standardize how {% data variables.product.prodname_copilot_short %} performs tasks in a specific context, such as a code review. +* Provide instructions when they are relevant, without adding them to every interaction. +* Avoid filling the context window with instructions unrelated to the current task. + +### When should you use a skill? + +Use a skill when you want: + +* A repeatable workflow. For example, check that user-facing documentation is updated when frontend code changes. +* A consistent output format. For example, draft release notes using your team's template. +* A workflow you sometimes need, but not always. For example, follow a detailed refactoring process during a migration. + +### When shouldn't you use a skill? + +Choose another customization when: + +* The guidance should apply broadly to your work. Use custom instructions instead. +* You need access to an external system. Use an MCP server to provide the tools, which a skill can then describe how to use. +* You need a reusable specialist with a particular toolset. Consider a custom agent. + +### Find out more about agent skills + +See [AUTOTITLE](/copilot/concepts/customizations/agent-skills). + +## Tools + +Tools are available to agents in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, and supported IDEs. The available tools and permission controls depend on the surface. + +### What is a tool? + +A tool is an ability that {% data variables.product.prodname_copilot_short %} uses to get something done, such as searching files, viewing file contents, editing, or running commands. Some tools are built in, and others can be added through MCP servers or extensions. + +### What problem do tools solve? + +Tools let an agent: + +* Gather context by reading and searching. +* Make changes by editing files. +* Execute commands and validate the results. + +### When are tools used? + +You typically do not call tools directly. {% data variables.product.prodname_copilot_short %} chooses tools to carry out your request, subject to the permissions and controls of the surface you are using. + +You will see tools used when you: + +* Ask an agent to search a repository, update a file, or run tests. +* Ask for work that requires access to an external service through an MCP server. +* Give an agent a task that benefits from delegation to a subagent. + +Before adding an integration, check whether the agent's existing tools already meet your needs. + +## MCP servers + +MCP servers are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, {% data variables.copilot.copilot_code-review_short %}, {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, {% data variables.jetbrains.prodname_jetbrains_ides %}, Xcode, and Eclipse. Configuration and authentication options depend on the surface. + +### What is an MCP server? + +An MCP server is a service that allows AI applications, such as {% data variables.product.prodname_copilot_short %}, to connect to external data sources and tools. + +For example, you could add an MCP server that provides tools for interacting with an online calendar or a support ticketing system. + +### What problem do MCP servers solve? + +MCP servers help when the built-in tools are not enough. They can: + +* Connect {% data variables.product.prodname_copilot_short %} to external systems. +* Add purpose-built tools for working with APIs, databases, or other services. +* Provide access to information outside your repository. + +### When should you use an MCP server? + +Use an MCP server when you need: + +* Information from an external system. For example: "How many support tickets have been opened this month for Product X?" +* Actions in another service. For example: "Add a comment to the support ticket summarizing this fix." + +### When shouldn't you use an MCP server? + +Avoid adding an MCP server when the built-in tools already cover your needs. + +### Find out more about MCP servers + +See [AUTOTITLE](/copilot/concepts/customizations/mcp). + +## Hooks + +Hooks are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, and {% data variables.product.prodname_vscode %}. Supported events and controls depend on the surface. + +### What is a hook? + +A hook runs a shell command you define at a particular point in an agent's workflow. For example, a hook can run before a tool is used or when a session ends. + +Unlike skills and custom instructions, which guide the model through prompts, hooks execute code at defined events. + +### What problem do hooks solve? + +Hooks help when you need more control over agent actions, such as: + +* Checking a tool request before allowing it to run. +* Logging tool use or session activity. +* Running custom validation at a supported event. + +### When should you use hooks? + +Use hooks when you want: + +* Tool checks. For example, check a proposed command against an allowlist before it runs. +* Session automation. For example, record when an agent session starts or ends. +* Custom validation. For example, check whether a tool request would change a protected path. + +Use the event and configuration reference for your surface rather than assuming that a hook works unchanged everywhere. + +### When shouldn't you use hooks? + +Choose another customization when: + +* You just need workflow instructions. Use a skill. +* You want persistent preferences and standards. Use custom instructions. +* You need access to external tools. Use an MCP server. + +### Find out more about hooks + +* [AUTOTITLE](/copilot/concepts/customizations/hooks) +* [AUTOTITLE](/copilot/reference/hooks-reference) + +## Subagents + +Subagents are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.product.prodname_vscode %}, {% data variables.jetbrains.prodname_jetbrains_ides %}, Xcode, and Eclipse. + +### What is a subagent? + +A subagent is an agent that the main agent delegates a specific piece of work to. It works in its own conversation context and reports its results back to the main agent. + +A subagent can use a built-in agent or a custom agent profile. You do not need to define a custom agent for every delegated task. + +### What problem do subagents solve? + +Subagents help an agent: + +* Keep the main conversation focused by handling a subtask in separate context. +* Run independent tasks in parallel where supported. +* Delegate specialist work using a custom agent profile. + +### When are subagents used? + +Subagents are useful for: + +* Codebase exploration. For example, find all endpoints in an API. +* Command execution. For example, run a test suite and summarize failures. +* Reviewing changes. For example, review staged changes while the main agent works on another part of the task. +* Specialist work. For example, delegate a review to a custom documentation agent. + +Selecting a custom agent for your main session is different from delegating work to it as a subagent. + +### Find out more about subagents + +* [AUTOTITLE](/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/delegating-and-parallelizing-work-with-agents) +* [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-subagents) + +## Custom agents + +Custom agents are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, {% data variables.jetbrains.prodname_jetbrains_ides %}, Eclipse, and Xcode. Supported profile properties depend on the surface. + +### What is a custom agent? + +A custom agent defines a specialist role, with instructions and available tools for a particular kind of work. You can think of it as a persona that {% data variables.product.prodname_copilot_short %} can adopt, such as a React reviewer or a docs writer. + +You define a custom agent in a Markdown file with YAML frontmatter. Its profile describes its purpose, gives it instructions, and can restrict its available tools. In supported environments, it can also configure MCP servers. + +### What problem do custom agents solve? + +Custom agents help when you need: + +* Specialist guidance applied consistently to particular tasks. +* A different set of tools for different kinds of work. +* A reusable role you can select for a session or use for delegated work. + +Separate context is a benefit of running an agent as a subagent, not a requirement for using a custom agent. + +### When should you use a custom agent? + +Use a custom agent when you want: + +* A specialized reviewer or helper. For example, a React reviewer that checks your team's component patterns. +* A constrained toolset. For example, a reviewer with tools for reading and searching files, but not editing them. +* A consistent approach. For example, a documentation agent that follows your writing and review standards. + +### When shouldn't you use a custom agent? + +Choose a simpler option when: + +* You only need task-specific instructions and resources. A skill may be enough. +* You do not need specialization and the default agent performs the task well. + +### Find out more about custom agents + +* [AUTOTITLE](/copilot/concepts/customizations/custom-agents) +* [AUTOTITLE](/copilot/reference/custom-agents-configuration) + +## Extensions + +Extensions are supported in the {% data variables.copilot.github_copilot_app %} and {% data variables.copilot.copilot_cli_short %}. The examples below describe extensions for {% data variables.copilot.copilot_cli_short %}. + +### What is an extension? + +An extension adds capabilities implemented in code. In {% data variables.copilot.copilot_cli_short %}, an extension is a JavaScript module that runs alongside an interactive session and can add tools, slash commands, and session-aware behavior. + +These are distinct from IDE extensions and the retired {% data variables.product.prodname_github_app %}-based {% data variables.product.prodname_copilot_short %} Extensions integration. + +### What problem do extensions solve? + +Extensions let you build capabilities that need more than instructions or configuration. For example, a {% data variables.copilot.copilot_cli_short %} extension can keep state across tool calls and make it available through a custom tool. + +### When should you use an extension? + +Use an extension when you need: + +* Your own session-aware tools. For example, track tool-call timings across a {% data variables.copilot.copilot_cli_short %} session and expose the totals to the agent. +* A slash command backed by code. For example, add a command that summarizes information collected during a {% data variables.copilot.copilot_cli_short %} session. + +### When shouldn't you use an extension? + +Choose another customization when: + +* Instructions and resources are enough. Use a skill. +* An existing MCP server provides the external tools you need. +* You only need to run a command at a defined event. Use a hook. + +### Find out more about extensions + +See [AUTOTITLE](/copilot/concepts/customizations/extensions). + +## Plugins + +Plugins are supported in the {% data variables.copilot.github_copilot_app %}, {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, and {% data variables.product.prodname_vscode %}. A plugin's supported components depend on the surface. + +### What is a plugin? + +A plugin is an installable package that delivers a bundle of capabilities. For example, it can include skills, custom agents, hooks, and MCP server configurations. + +A plugin packages customizations, but does not replace their individual purposes. + +### What problem do plugins solve? + +Plugins help you: + +* Add related capabilities without configuring each piece separately. +* Distribute a set of customizations to your team or the public. +* Install and update customizations without manually copying files. + +### When should you use a plugin? + +Use a plugin when: + +* You want a team-wide bundle. For example, share incident-response skills, a review agent, and MCP server configuration for internal services. +* You want to install and maintain related capabilities together. + +### When shouldn't you use a plugin? + +Start with individual customizations when: + +* You are experimenting locally and do not need distribution. +* You only need a small workflow. A single skill may be simpler. + +### Find out more about plugins + +See [AUTOTITLE](/copilot/concepts/customizations/plugins). + +## Putting it together: choosing the right option + +Start with the smallest customization that solves your problem. These features can work together: a skill can describe a workflow that uses MCP tools, and a plugin can distribute both. + +| Requirement | Start with | +| --- | --- | +| I want {% data variables.product.prodname_copilot_short %} to follow our repository conventions. | Custom instructions | +| I want a repeatable workflow for a particular kind of task. | Agent skills | +| I want an agent to search my repository, change files, or run tests. | Its existing tools | +| I need tools provided by an external service. | An MCP server | +| I want checks or automation around tool use and session events. | Hooks | +| I want a focused subtask handled separately from the main conversation. | Subagents | +| I want a reusable specialist with a particular approach and toolset. | A custom agent | +| I need to build my own session-aware tools in {% data variables.copilot.copilot_cli_short %}. | An extension | +| I want to install or share related customizations together. | A plugin | + +## Next steps + +For configuration locations and surface support, see [AUTOTITLE](/copilot/reference/customization-cheat-sheet). diff --git a/content/copilot/concepts/customizations/custom-agents.md b/content/copilot/concepts/customizations/custom-agents.md new file mode 100644 index 000000000000..d703aa4e52a8 --- /dev/null +++ b/content/copilot/concepts/customizations/custom-agents.md @@ -0,0 +1,73 @@ +--- +title: Custom agents +shortTitle: Custom agents +intro: 'Give {% data variables.product.prodname_copilot_short %} reusable specialist roles with tailored instructions and tools.' +versions: + feature: copilot +contentType: concepts +redirect_from: + - /copilot/concepts/agents/about-custom-agents + - /copilot/concepts/agents/cloud-agent/about-custom-agents + - /copilot/concepts/agents/copilot-cli/about-custom-agents + - /copilot/concepts/agents/coding-agent/about-custom-agents +category: + - Learn about Copilot + - Learn about Copilot CLI +--- + +{% data variables.copilot.custom_agents_caps_short %} are specialized versions of the {% data variables.product.prodname_copilot_short %} agent that you tailor to particular tasks and workflows. Define a role once instead of repeating its instructions and tool requirements every time you need that expertise. + +For example, you can create a documentation specialist that follows your writing standards, or a reviewer that can read and search files but does not need editing tools. + +## About agent profiles + +An agent profile is a Markdown file with YAML frontmatter. It describes the agent's purpose, gives it instructions, and can restrict its available tools. In supported environments, a profile can also configure MCP servers for that agent. + +Use a custom agent when you need a reusable role with a particular approach and toolset. If you only need task-specific instructions and resources, a skill can be a simpler choice. For a comparison, see [AUTOTITLE](/copilot/concepts/customizations/comparing-customizations). + +Profiles can be shared at repository, organization, and enterprise levels. {% data variables.copilot.copilot_cli_short %} also supports personal profiles. Configuration locations, supported properties, and precedence depend on the environment. See [AUTOTITLE](/copilot/reference/custom-agents-configuration). + +## Where you can use custom agents + +You can use custom agents with: + +* **The {% data variables.copilot.github_copilot_app %}**. +* **{% data variables.copilot.copilot_cli %}**. +* **{% data variables.copilot.copilot_cloud_agent %} on {% data variables.product.prodname_dotcom_the_website %}**, including the agents tab and panel, issue assignment, and pull requests. +* **Supported IDEs**, including {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, {% data variables.jetbrains.prodname_jetbrains_ides %}, Eclipse, and Xcode. + +Custom agents in {% data variables.jetbrains.prodname_jetbrains_ides %} and Xcode are in {% data variables.release-phases.public_preview %}. For IDE-specific version support and release status, see [AUTOTITLE](/copilot/reference/copilot-feature-matrix). + +In an IDE, using a custom agent directly in chat is different from delegating a task to {% data variables.copilot.copilot_cloud_agent %}. A profile's properties can behave differently or be ignored between environments. For {% data variables.product.prodname_vscode_shortname %} profile behavior, see [Custom agents in {% data variables.product.prodname_vscode_shortname %}](https://code.visualstudio.com/docs/copilot/customization/custom-agents). + +## Built-in agents + +You do not need to define a custom agent for every specialist task. {% data variables.copilot.copilot_cli_short %} includes built-in agents that the main agent can use for common work: + +* `explore` for codebase exploration +* `task` for command execution +* `general-purpose` for work requiring a separate agent context +* `code-review` for reviewing changes +* `research` for research +* `rubber-duck` for a second opinion +* `security-review` for security-focused review + +These are provided by {% data variables.copilot.copilot_cli_short %}, rather than authored as your own profiles. The available tools and behavior differ by agent. For their capabilities and model defaults, see [Built-in agents](/copilot/reference/copilot-cli-reference/cli-command-reference#built-in-agents). + +## Custom agents and subagents + +A custom agent is a **definition of a specialist**. A subagent is **an agent doing delegated work** in a separate context window. The main agent can delegate to a built-in agent or run a specialist using a custom agent profile. + +Separate context lets a subagent focus on its assigned task without adding every intermediate detail to the main conversation. Independent tasks can also run in parallel. These are benefits of delegation, not properties that require you to create a custom profile. + +Selecting a custom agent for a session and delegating a subtask to one are different ways of using a profile. In {% data variables.copilot.copilot_cli_short %}, repository instructions are included for the session agent but are not included for a custom subagent by default. For the opt-in setting and invocation methods, see [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli). + +For the broader delegation model in the {% data variables.copilot.github_copilot_app %} and {% data variables.copilot.copilot_cli_short %}, see [AUTOTITLE](/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/delegating-and-parallelizing-work-with-agents). + +## Next steps + +Choose the setup guide for where you work: + +* [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents) +* [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-custom-agents) +* [AUTOTITLE](/copilot/how-tos/github-copilot-app/customize-github-copilot-app) diff --git a/content/copilot/concepts/customizations/extensions.md b/content/copilot/concepts/customizations/extensions.md new file mode 100644 index 000000000000..e0b783f6e289 --- /dev/null +++ b/content/copilot/concepts/customizations/extensions.md @@ -0,0 +1,73 @@ +--- +title: Extensions for GitHub Copilot +shortTitle: Extensions +intro: 'Extend {% data variables.product.prodname_copilot_short %} with capabilities implemented in code.' +versions: + feature: copilot +contentType: concepts +redirect_from: + - /copilot/concepts/agents/copilot-cli/about-cli-extensions +category: + - Learn about Copilot + - Learn about Copilot CLI +--- + +Extensions let you implement capabilities that go beyond prompting the agent. For example, in {% data variables.copilot.copilot_cli %}, an extension can add tools and slash commands backed by code running alongside your session. + +These extensions are distinct from the retired {% data variables.product.prodname_github_app %}-based {% data variables.product.prodname_copilot_short %} Extensions integration. They are also distinct from IDE extensions, such as the {% data variables.product.prodname_copilot_short %} extension you install in an editor. + +## Where you can use extensions + +You can use extensions in: + +* The {% data variables.copilot.github_copilot_app %}. +* {% data variables.copilot.copilot_cli %}. + +For customization options in the {% data variables.copilot.github_copilot_app %}, see [AUTOTITLE](/copilot/how-tos/github-copilot-app/customize-github-copilot-app). + +{% data reusables.copilot.copilot-cli.cli-extensions-experimental %} + +## Choosing an extension scope + +Choose an extension's scope based on who needs it: + +* **Repository extensions** keep project-specific capabilities with the project so you can share them with collaborators. +* **Personal extensions** provide capabilities for your own workflows. +* **Plugin extensions** are supplied as part of an installed plugin, alongside other customizations. + +To create an extension for {% data variables.copilot.copilot_cli_short %}, see [AUTOTITLE](/copilot/tutorials/create-an-extension). + +## Extensions in {% data variables.copilot.copilot_cli_short %} + +An extension for {% data variables.copilot.copilot_cli_short %} is a JavaScript module that runs as a separate Node.js process alongside an interactive session. It connects to the session through the extension SDK bundled with {% data variables.copilot.copilot_cli_short %}. + +An extension can add: + +* **Tools** that the agent can call while working on your request. +* **Slash commands** that you invoke yourself. +* Session-aware behavior, such as observing events and keeping state across tool calls. + +Use an extension when a capability needs code that stays active during the session. For example, an extension can track tool-call timings across a session and expose the totals through a tool. + +{% data variables.copilot.copilot_cli_short %} also lets you control whether extensions run and whether the agent can manage them. For the extension modes and their effects, see [Extension modes](/copilot/reference/copilot-cli-reference/cli-command-reference#extension-modes). + +## Choosing between extensions and other customizations + +The distinction is the capability you need, not just where you install it: + +| Need | Start with | +| --- | --- | +| A repeatable workflow expressed as instructions and resources | An agent skill | +| Access to tools exposed by an external service | An MCP server | +| A command at a defined agent lifecycle event | A hook | +| Session-aware tools or slash commands implemented in JavaScript | An extension for {% data variables.copilot.copilot_cli_short %} | +| A distributable bundle of related capabilities | A plugin | + +A plugin can distribute extensions, but the surface determines how those extensions are used. + +> [!WARNING] +> Extensions for {% data variables.copilot.copilot_cli_short %} execute on your computer with your privileges. Only load extension code that you trust, just as you would for any other script you did not write yourself. + +## Next steps + +To compare extensions with the other customization options, see [AUTOTITLE](/copilot/concepts/customizations/comparing-customizations). diff --git a/content/copilot/concepts/agents/hooks.md b/content/copilot/concepts/customizations/hooks.md similarity index 73% rename from content/copilot/concepts/agents/hooks.md rename to content/copilot/concepts/customizations/hooks.md index 672e2d5a4d8e..8218af284fe4 100644 --- a/content/copilot/concepts/agents/hooks.md +++ b/content/copilot/concepts/customizations/hooks.md @@ -1,7 +1,7 @@ --- -title: About hooks for {% data variables.product.prodname_copilot %} +title: Hooks for {% data variables.product.prodname_copilot %} shortTitle: Hooks -intro: 'Extend and customize {% data variables.product.prodname_copilot %} agent behavior by executing custom shell commands at key points during agent execution.' +intro: 'Run your own checks, logging, or other commands at defined points while a {% data variables.product.prodname_copilot_short %} agent works.' versions: feature: copilot contentType: concepts @@ -11,6 +11,7 @@ redirect_from: - /copilot/concepts/agents/coding-agent/about-hooks - /copilot/concepts/agents/cloud-agent/about-hooks - /copilot/concepts/agents/about-hooks + - /copilot/concepts/agents/hooks --- ## What are hooks? @@ -23,16 +24,24 @@ Hooks receive detailed information about agent actions via JSON input, enabling * Use built-in security features like secret scanning to prevent credential leaks. * Implement custom validation rules and audit logging for compliance. -Hooks are available for use with: +Unlike custom instructions, hooks run code rather than asking the model to follow a rule. For example, a hook can run a script that checks a tool request before it executes. -* **{% data variables.copilot.copilot_cloud_agent %}** on {% data variables.product.github %}. -* **{% data variables.copilot.copilot_cli %}** in your terminal. +## Where you can use hooks -You define hooks in JSON files, stored in your repository at `.github/hooks/*.json`. These apply whenever {% data variables.product.prodname_copilot_short %} agents are used in the repository. {% data variables.copilot.copilot_cli_short %} also supports personal hooks that you store in your home directory at `~/.copilot/hooks/*.json`. These apply whenever you use {% data variables.copilot.copilot_cli_short %}. +Hooks are available in: + +* **The {% data variables.copilot.github_copilot_app %}**, which supports repository hooks and hooks supplied by plugins. See [AUTOTITLE](/copilot/how-tos/github-copilot-app/customize-github-copilot-app). +* **{% data variables.copilot.copilot_cli %}**, where commands run in its execution environment. +* **{% data variables.copilot.copilot_cloud_agent %}**, where commands run in the agent's cloud environment. Only a subset of events is supported. +* **{% data variables.product.prodname_vscode %}**, where the hooks experience is in {% data variables.release-phases.public_preview %}. Supported events and configuration depend on the agent running the session. See [Agent hooks in {% data variables.product.prodname_vscode_shortname %}](https://code.visualstudio.com/docs/agent-customization/hooks). + +The configuration and examples below describe hooks for {% data variables.copilot.copilot_cli_short %} and {% data variables.copilot.copilot_cloud_agent %}. Do not assume that the same events, input, or output work unchanged across surfaces. + +For {% data variables.copilot.copilot_cli_short %} and {% data variables.copilot.copilot_cloud_agent %}, you can define repository hooks in `.github/hooks/*.json`. {% data variables.copilot.copilot_cli_short %} also supports personal hooks in `~/.copilot/hooks/*.json`. For execution environments, additional locations, and event support, see [AUTOTITLE](/copilot/reference/hooks-reference). ## Types of hooks -The following types of hooks are available: +These are examples of {% data variables.copilot.copilot_cli_short %} hook events. {% data variables.copilot.copilot_cloud_agent %} supports a subset: * **sessionStart**: Executed when a new agent session begins or when resuming an existing session. Can be used to initialize environments, log session starts for auditing, validate project state, and set up temporary resources. * **sessionEnd**: Executed when the agent session completes or is terminated. Can be used to cleanup temporary resources, generate and archive session reports and logs, or send notifications about session completion. @@ -43,7 +52,7 @@ The following types of hooks are available: * **subagentStop**: Executed when a subagent completes, before returning results to the parent agent. * **errorOccurred**: Executed when an error occurs during agent execution. Can be used to log errors for debugging, send notifications, track error patterns, and generate reports. -To see a complete reference of hook types with example use cases, best practices, and advanced patterns, see [AUTOTITLE](/copilot/reference/hooks-reference). +The hooks reference lists the full set of events and their availability in {% data variables.copilot.copilot_cloud_agent %}. ## Hook configuration format @@ -80,7 +89,7 @@ The hook object can contain the following keys: ## Example hook configuration file -This is an example configuration file that lives in `~/.github/hooks/project-hooks.json` within a repository. +This is an example configuration file that lives in `.github/hooks/project-hooks.json` within a repository. ```json copy { diff --git a/content/copilot/concepts/customizations/index.md b/content/copilot/concepts/customizations/index.md new file mode 100644 index 000000000000..b45bf9dd7a01 --- /dev/null +++ b/content/copilot/concepts/customizations/index.md @@ -0,0 +1,17 @@ +--- +title: Customizations for GitHub Copilot +shortTitle: Customizations +intro: Extend {% data variables.copilot.copilot_cli_short %} for your own workflows, and for organizations, standardize how {% data variables.copilot.copilot_cli_short %} is customized across teams. +versions: + feature: copilot +children: + - /comparing-customizations + - /agent-skills + - /custom-agents + - /mcp + - /hooks + - /extensions + - /plugins + - /lsp-servers +contentType: concepts +--- diff --git a/content/copilot/concepts/agents/copilot-cli/lsp-servers.md b/content/copilot/concepts/customizations/lsp-servers.md similarity index 86% rename from content/copilot/concepts/agents/copilot-cli/lsp-servers.md rename to content/copilot/concepts/customizations/lsp-servers.md index 3628b4247964..cf622465f5ef 100644 --- a/content/copilot/concepts/agents/copilot-cli/lsp-servers.md +++ b/content/copilot/concepts/customizations/lsp-servers.md @@ -5,6 +5,8 @@ allowTitleToDifferFromFilename: true intro: 'LSP servers give {% data variables.copilot.copilot_cli_short %} precise code intelligence, enabling it to navigate definitions, find references, and rename symbols accurately across your project.' versions: feature: copilot +redirect_from: + - /copilot/concepts/agents/copilot-cli/lsp-servers contentType: concepts docsTeamMetrics: - copilot-cli @@ -23,7 +25,7 @@ The Language Server Protocol (LSP) is an open standard used for communication be * **Accuracy**: Results come from the language's own compiler/analyzer, providing an understanding of the structure of your code. This improves {% data variables.product.prodname_copilot_short %}'s precision when it works with your code. For example, when {% data variables.product.prodname_copilot_short %} can use "go to definition" it will find the actual definition, not a text match that looks similar. * **Token efficiency**: Operations like "list all symbols" or "find references" return compact structured results instead of requiring the agent to read entire files into the conversation. -* **Safe refactoring**: When you rename a symbol, the LSP server reliably updates every reference across the project. +* **Refactoring**: The language server can find and update references when renaming a symbol, rather than relying on text replacement. * **Speed**: Language servers index your project in the background, allowing near-instant responses. ## What LSP servers allow {% data variables.copilot.copilot_cli_short %} to do @@ -50,7 +52,7 @@ The following language server operations are supported: For {% data variables.copilot.copilot_cli_short %} to be able to use an LSP server, you must first install the server software on your local machine and then configure it in one of the configuration files that {% data variables.copilot.copilot_cli_short %} reads on startup. See [AUTOTITLE](/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers). -An LSP server may also be added as part of a CLI plugin that you choose to install. A plugin might include an LSP server if, for example, it's designed to work with an uncommon programming language or a framework-specific file type. LSP servers included as part of a plugin are automatically available when you install the plugin—no additional configuration is needed. If you uninstall the plugin, the LSP server is removed. For more information, see [AUTOTITLE](/copilot/concepts/agents/about-plugins). +An LSP server may also be added as part of a {% data variables.copilot.copilot_cli_short %} plugin that you choose to install. A plugin might include an LSP server if, for example, it's designed to work with an uncommon programming language or a framework-specific file type. LSP servers included as part of a plugin are automatically available when you install the plugin—no additional configuration is needed. If you uninstall the plugin, the LSP server is removed. For more information, see [AUTOTITLE](/copilot/concepts/customizations/plugins). ## How LSP servers are loaded diff --git a/content/copilot/concepts/context/mcp.md b/content/copilot/concepts/customizations/mcp.md similarity index 55% rename from content/copilot/concepts/context/mcp.md rename to content/copilot/concepts/customizations/mcp.md index c412343d3582..78c566ba9373 100644 --- a/content/copilot/concepts/context/mcp.md +++ b/content/copilot/concepts/customizations/mcp.md @@ -1,12 +1,16 @@ --- -title: About Model Context Protocol (MCP) +title: Model Context Protocol (MCP) allowTitleToDifferFromFilename: true shortTitle: MCP -intro: Model Context Protocol (MCP) is a protocol that allows you to extend the capabilities of {% data variables.product.prodname_copilot %} by integrating it with other systems. +intro: 'Connect {% data variables.product.prodname_copilot_short %} to external tools and data through Model Context Protocol (MCP) servers.' versions: feature: copilot contentType: concepts redirect_from: + - /copilot/concepts/context/mcp + - /copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent + - /copilot/concepts/agents/coding-agent/mcp-and-coding-agent + - /copilot/concepts/coding-agent/mcp-and-coding-agent - /copilot/concepts/about-mcp - /copilot/concepts/extensions/agents - /copilot/concepts/extensions/build-extensions @@ -30,6 +34,7 @@ redirect_from: - /copilot/using-github-copilot/using-extensions-to-integrate-external-tools-with-copilot-chat category: - Learn about Copilot + - Integrate Copilot with your tools --- ## Overview of Model Context Protocol (MCP) @@ -38,25 +43,67 @@ category: You can use MCP to extend the capabilities of {% data variables.product.prodname_copilot %} by integrating it with a wide range of existing tools and services. MCP works across all major {% data variables.product.prodname_copilot_short %} surfaces—whether you're working in an IDE, using {% data variables.copilot.copilot_cli %}, working in the {% data variables.copilot.github_copilot_app %}, or delegating tasks to an agent on {% data variables.product.prodname_dotcom_the_website %}. You can also use MCP to create new tools and services that work with {% data variables.product.prodname_copilot_short %}, allowing you to customize and enhance your experience. -For more information on MCP, see [the official MCP documentation](https://modelcontextprotocol.io/introduction). For a curated list of MCP servers from partners and the community, see the [{% data variables.product.github %} MCP Registry](https://github.com/mcp). +For example, you can connect an issue tracker so {% data variables.product.prodname_copilot_short %} can look up a bug while working on a fix, without asking you to copy the issue into chat. -To learn how to configure and use MCP servers, see: +For more information on MCP, see [the official MCP documentation](https://modelcontextprotocol.io/introduction). For a curated list of MCP servers from partners and the community, see the [{% data variables.product.github %} MCP Registry](https://github.com/mcp). -* [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp) for {% data variables.copilot.copilot_chat_short %} in your IDE -* [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers) for {% data variables.copilot.copilot_cli_short %} -* [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers) for repository MCP configuration on {% data variables.product.prodname_dotcom_the_website %} -* [AUTOTITLE](/copilot/how-tos/github-copilot-app/customize-github-copilot-app) for information on MCP server support in the {% data variables.copilot.github_copilot_app %} {% data reusables.copilot.mcp.mcp-policy %} -## Availability +MCP complements the context you provide through prompts, files, and instructions. It adds connections to tools and data, rather than replacing guidance about how the agent should work. For guidance about prompting and managing context, see [AUTOTITLE](/copilot/concepts/prompting-and-context). -MCP is supported across the following clients: +## Where you can use MCP -* **IDEs**: There is broad support for local MCP servers in clients such as {% data variables.product.prodname_vscode %}, JetBrains IDEs, Xcode, and others. Support for remote MCP servers is growing, with editors like {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, JetBrains IDEs, Xcode, Eclipse, Cursor, and Windsurf providing this functionality with OAuth or PAT. To find out if your preferred editor supports remote MCP servers, check the documentation for your specific editor. +MCP setup depends on where you use {% data variables.product.prodname_copilot_short %}: + +* **The {% data variables.copilot.github_copilot_app %}**: You can use MCP servers configured for your repository or in your local {% data variables.product.prodname_copilot_short %} configuration. You can also discover and install additional MCP servers from the **Customize** tab. * **{% data variables.copilot.copilot_cli_short %}**: {% data variables.copilot.copilot_cli %} supports both local and remote MCP servers. The {% data variables.product.github %} MCP server is built in and available without additional configuration. -* **The {% data variables.copilot.github_copilot_app %}**: The {% data variables.copilot.github_copilot_app %} supports MCP servers configured in your repository or {% data variables.copilot.copilot_cli_short %} and lets you add additional MCP servers in app settings. -* **Chat on {% data variables.product.prodname_dotcom_the_website %}**: Chat is preconfigured with tools for tasks such as creating branches, updating files, and semantic code search. See [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-on-github). * **{% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %}**: {% data variables.product.prodname_dotcom_the_website %} supports MCP servers configured at the repository level. The configuration applies to both {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %}. The {% data variables.product.github %} MCP server and Playwright MCP server are configured by default. +* **IDEs**: MCP servers are supported in {% data variables.product.prodname_vscode %}, {% data variables.product.prodname_vs %}, {% data variables.jetbrains.prodname_jetbrains_ides %}, Xcode, and Eclipse. Connection and authentication options depend on the IDE. See [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp). + +Chat on {% data variables.product.prodname_dotcom_the_website %} has preconfigured tools, such as tools for creating branches and searching code. This is separate from the repository MCP settings for {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %}. See [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-on-github). + +## MCP for {% data variables.copilot.copilot_cloud_agent %} + +The following sections describe MCP defaults and configuration for {% data variables.copilot.copilot_cloud_agent %}. Repository-level MCP settings also apply to {% data variables.copilot.copilot_code-review_short %}, as noted below. For other surfaces, use the setup guides in [Next steps](#next-steps). + +### Default MCP servers + +{% data variables.copilot.copilot_cloud_agent %} starts with two MCP servers configured: + +* **{% data variables.product.github %}** provides access to repository data such as issues and pull requests. By default, it uses a specially scoped token with read-only access to the current repository. Access outside that repository requires explicitly configuring credentials with broader access. +* **Playwright** provides tools to read, interact with, and take screenshots of web pages. By default, it can only access web resources in the agent's own environment through `localhost` or `127.0.0.1`. + +These defaults are specific to the cloud environment. For example, {% data variables.copilot.copilot_cli_short %} includes the {% data variables.product.github %} MCP server without additional configuration, but you configure other servers separately. + +### Repository-level configuration + +Repository administrators can configure MCP servers in repository settings on {% data variables.product.prodname_dotcom_the_website %}. These settings are shared by {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %}. You can disable MCP tool use for code review separately. + +This repository setting is distinct from project MCP configuration files used by {% data variables.copilot.copilot_cli_short %}. Use the setup guide for your surface rather than assuming that the same configuration location applies everywhere. + +> [!WARNING] +> {% data variables.copilot.copilot_cloud_agent %} uses configured MCP tools autonomously and does not ask for approval before calling them. Review each server and allow only the tools and access needed for your tasks. + +{% data reusables.copilot.mcp.repo-mcp-limitations %} + +{% data variables.copilot.copilot_code-review_short %} additionally requires tools to declare `annotations.readOnlyHint: true`. Tools with this annotation missing or set to `false` are excluded. + +For configuration, authentication, and validation procedures, see [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers). + +### MCP servers for custom agents + +For {% data variables.copilot.copilot_cloud_agent %}, an agent profile can define MCP servers for that custom agent, rather than making them available to every agent working in the repository. The `mcp-servers` profile property is not used by custom agents running directly in IDEs. + +For {% data variables.copilot.copilot_cloud_agent %}, default server configurations are processed first, then custom agent configurations, then repository settings. Later configurations can override earlier settings. This order does not describe project-file precedence in {% data variables.copilot.copilot_cli_short %}. + +For the profile format, supported properties, and processing rules, see [AUTOTITLE](/copilot/reference/custom-agents-configuration). + +## Best practices + +* Review third-party servers before enabling them. Check their tools, authentication requirements, and data access against your organization's requirements. +* Enable only the tools a task needs. In repository settings, use the `tools` field to allowlist specific tools, preferably read-only tools, rather than enabling every tool. +* Keep credentials scoped to the required resources. Do not broaden the default token's access for {% data variables.copilot.copilot_cloud_agent %} unless the task needs it. +* Validate configuration before relying on it. Confirm which servers and tools are available in your agent session. For setup instructions for your environment, see [Next steps](#next-steps). ## About the {% data variables.product.github %} MCP server @@ -69,7 +116,7 @@ The {% data variables.product.github %} MCP server is a Model Context Protocol ( * Enable cloud-based workflows that work from any device, without local setup. * Invoke {% data variables.product.github %} tools, such as {% data variables.copilot.copilot_cloud_agent %} (requires {% data variables.product.prodname_copilot %} subscription) and {% data variables.product.prodname_code_scanning %} (requires {% data variables.product.prodname_GHAS %} subscription), to assist with code generation and security analysis. -To learn how to set up and use the {% data variables.product.github %} MCP server, see [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/copilot-for-common-tasks/use-the-github-mcp-server). +To learn how to use the {% data variables.product.github %} MCP server, see [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/copilot-for-common-tasks/use-the-github-mcp-server). To find out whether your editor supports the {% data variables.product.github %} MCP server, and which connection and authentication methods are available, see [Support by host application](https://github.com/github/github-mcp-server/blob/main/docs/installation-guides/README.md#support-by-host-application) in the `github/github-mcp-server` repository. @@ -98,22 +145,21 @@ For all public repositories, and private repositories covered by {% data variabl ## About the {% data variables.product.github %} MCP Registry -The {% data variables.product.github %} MCP Registry is a curated list of MCP servers from partners and the community. You can use the registry to discover new MCP servers and find ones that meet your specific needs. See [the {% data variables.product.github %} MCP Registry](https://github.com/mcp). +The {% data variables.product.github %} MCP Registry is a curated list of MCP servers from partners and the community. You can use the registry to discover new MCP servers and find ones that meet your specific needs. ->[!NOTE] +> [!NOTE] > The {% data variables.product.github %} MCP Registry is currently in {% data variables.release-phases.public_preview %} and subject to change. ## Agent finder Agent finder is a discovery service that helps {% data variables.product.prodname_copilot %} find the right capabilities—such as MCP servers, tools, agents, and skills—for a task at runtime, instead of requiring every capability to be configured in advance. Like an MCP registry, it searches a catalog of capabilities and returns ranked matches that {% data variables.product.prodname_copilot %} can use on demand. Agent finder implements the open Agentic Resource Discovery (ARD) specification. -To use agent finder, download the [agent finder skill](https://github.com/ards-project/connectors/blob/main/skills/github-copilot/SKILL.md) and add it to your `~/.copilot/skills` directory. For more information about agent skills, see [AUTOTITLE](/copilot/concepts/agents/about-agent-skills). To browse the catalog, see [GitHub Agent Finder](https://github.com/agentfinder). +For {% data variables.copilot.copilot_cli_short %} setup, see [Using agent finder](/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers#using-agent-finder). The {% data variables.copilot.github_copilot_app %} provides an `af` built-in skill. See [AUTOTITLE](/copilot/reference/github-copilot-app-reference/built-in-skills). To browse the catalog, see [GitHub Agent Finder](https://github.com/agentfinder). ## Next steps -* [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp)—Add MCP servers to {% data variables.copilot.copilot_chat_short %} in your IDE +* [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers)—Add MCP servers to {% data variables.copilot.copilot_cli_short %} +* [AUTOTITLE](/copilot/how-tos/github-copilot-app/customize-github-copilot-app)—Manage MCP servers in the {% data variables.copilot.github_copilot_app %} * [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers)—Configure repository MCP servers for {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_code-review_short %} +* [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp)—Add MCP servers to {% data variables.copilot.copilot_chat_short %} in your IDE * [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/set-up-the-github-mcp-server)—Set up the {% data variables.product.github %} MCP server -* [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/copilot-for-common-tasks/use-the-github-mcp-server)—Use the {% data variables.product.github %} MCP server -* [AUTOTITLE](/copilot/tutorials/enhance-agent-mode-with-mcp) -* [AUTOTITLE](/copilot/reference/customization-cheat-sheet) diff --git a/content/copilot/concepts/agents/about-plugins.md b/content/copilot/concepts/customizations/plugins.md similarity index 77% rename from content/copilot/concepts/agents/about-plugins.md rename to content/copilot/concepts/customizations/plugins.md index 188c7fde9063..868565c27b29 100644 --- a/content/copilot/concepts/agents/about-plugins.md +++ b/content/copilot/concepts/customizations/plugins.md @@ -1,35 +1,45 @@ --- -title: About {% data variables.product.prodname_copilot %} plugins +title: Plugins for {% data variables.product.prodname_copilot %} shortTitle: Plugins allowTitleToDifferFromFilename: true -intro: 'Plugins are installable packages that extend {% data variables.product.prodname_copilot_short %} with reusable agents, skills, hooks, and integrations.' +intro: Plugins are installable packages that extend {% data variables.product.prodname_copilot_short %} with reusable agents, skills, hooks, and integrations. product: '{% data reusables.gated-features.copilot-cli %}

{% data reusables.gated-features.copilot-cloud-agent %}

{% data reusables.gated-features.github-app %}
Sign up for {% data variables.product.prodname_copilot_short %} {% octicon "link-external" height:16 %}' versions: feature: copilot contentType: concepts category: - - Learn about Copilot # Copilot discovery page - - Learn about Copilot CLI # Copilot CLI bespoke page + - Learn about Copilot + - Learn about Copilot CLI docsTeamMetrics: - copilot-cli redirect_from: - /copilot/concepts/agents/copilot-cli/about-cli-plugins + - /copilot/concepts/agents/about-plugins --- -Plugins provide a way to distribute custom {% data variables.product.prodname_copilot_short %} functionality. You can use a plugin to add a preconfigured set of capabilities to {% data variables.product.prodname_copilot_short %}, including {% data variables.copilot.copilot_cli_short %}, {% data variables.copilot.copilot_cloud_agent %}, and the {% data variables.copilot.github_copilot_app %}. +Plugins let you install related customizations together instead of setting up each one separately. For example, a testing plugin could combine a skill for running tests, a review agent, and an MCP server for a test-reporting service. -## What is a plugin? +## Where you can use plugins -* A distributable package that extends {% data variables.product.prodname_copilot_short %}'s functionality. -* A bundle of components in a single installable unit. +You can use plugins in: + +* The {% data variables.copilot.github_copilot_app %}. +* {% data variables.copilot.copilot_cli %}. +* {% data variables.copilot.copilot_cloud_agent %}. +* {% data variables.product.prodname_vscode %}. For supported components and installation, see [Agent plugins in {% data variables.product.prodname_vscode_shortname %}](https://code.visualstudio.com/docs/agent-customization/agent-plugins). + +A plugin can contain components that only work in a particular surface. Check that the plugin supports the surface you use. For example, the LSP server configuration described in this category is for {% data variables.copilot.copilot_cli_short %}. + +The component paths and directory examples below describe plugin formats for {% data variables.copilot.copilot_cli_short %}. Other surfaces can support different components. ## What plugins contain A plugin can contain some or all of the following components. The locations of these components depend on the plugin format: * **Custom agents** — Specialized AI assistants (`*.agent.md` files in `agents/`) -* **Skills** — Discrete callable capabilities (skills subdirectories in `skills/`, containing a `SKILL.md` file) +* **Skills** — Task-specific instructions, scripts, and resources (skills subdirectories in `skills/`, containing a `SKILL.md` file) * **Hooks** — Event handlers that intercept agent behavior (a `hooks.json` file in the plugin root, or in `hooks/`) +* **Extensions** — Code that adds capabilities such as tools and slash commands in supported surfaces * **MCP server configurations** — Model Context Protocol integrations * **LSP server configurations** — Language Server Protocol integrations (an `lsp.json` file in the plugin root, or in `.github/`) @@ -120,9 +130,10 @@ Examples of marketplaces include: How you install a plugin depends on which client you're using: -* In {% data variables.copilot.copilot_cli_short %}, you can install plugins imperatively using the `copilot plugin install` command or the `/plugin install` slash command, or declaratively by adding the plugin to the `enabledPlugins` field of either a user-level `~/.copilot/settings.json` file or a repository-level `.github/copilot/settings.json` file. See [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/plugins-finding-installing). -* In {% data variables.copilot.copilot_cloud_agent %}, you install plugins declaratively by adding them to the `enabledPlugins` field of the repository's `.github/copilot/settings.json` file. To install plugins from a marketplace that isn't registered by default, you can also add the marketplace to the `extraKnownMarketplaces` field in the same file. +* In {% data variables.copilot.copilot_cli_short %}, you can install plugins using the `copilot plugin install` command or the `/plugin install` slash command, or by adding the plugin to the `enabledPlugins` field of either a user-level `~/.copilot/settings.json` file or a repository-level `.github/copilot/settings.json` file. See [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/plugins-finding-installing). +* In {% data variables.copilot.copilot_cloud_agent %}, you install plugins by adding them to the `enabledPlugins` field of the repository's `.github/copilot/settings.json` file. To install plugins from a marketplace that isn't registered by default, you can also add the marketplace to the `extraKnownMarketplaces` field in the same file. * In the {% data variables.copilot.github_copilot_app %}, click **Customize**, then click **Plugins** to browse marketplaces and install plugins. +* In {% data variables.product.prodname_vscode %}, use the plugin marketplace commands described in the {% data variables.product.prodname_vscode_shortname %} documentation linked above. Enterprise administrators can define plugin standards that apply to users on the enterprise's {% data variables.product.prodname_copilot_short %} plan, including specifying additional marketplaces and plugins that are automatically installed. See [AUTOTITLE](/copilot/concepts/enterprise/plugin-standards). @@ -147,6 +158,7 @@ Any functionality that you could add with a plugin, you could also add by config ## Further reading +* [AUTOTITLE](/copilot/concepts/customizations/extensions) * [AUTOTITLE](/copilot/concepts/agents/about-agent-skills) * [AUTOTITLE](/copilot/concepts/agents/hooks) -* [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents) +* [AUTOTITLE](/copilot/concepts/customizations/custom-agents) diff --git a/content/copilot/concepts/enterprise/agent-management.md b/content/copilot/concepts/enterprise/agent-management.md index 002e2b050e0f..cb61e0c32990 100644 --- a/content/copilot/concepts/enterprise/agent-management.md +++ b/content/copilot/concepts/enterprise/agent-management.md @@ -37,7 +37,7 @@ You can manage your enterprise-level {% data variables.copilot.custom_agents_sho * From the AI Controls view * Using the REST API. See [AUTOTITLE](/rest/copilot/copilot-custom-agents). -For more detailed information on {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +For more detailed information on {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents). ## Agent sessions diff --git a/content/copilot/concepts/enterprise/default-availability.md b/content/copilot/concepts/enterprise/default-availability.md index 64e31b3fcaf7..328889d8a21e 100644 --- a/content/copilot/concepts/enterprise/default-availability.md +++ b/content/copilot/concepts/enterprise/default-availability.md @@ -91,7 +91,7 @@ Model status | Description **Enabled** or **Disabled** | Explicitly configured. **Does not follow** the default availability policy. **Delegate to default policy** | Has not been configured. **Follows** the default availability policy. **Unconfigured** | Has not been configured. **Does not follow** the default availability policy. For example, a model in preview. -**Delegate to organizations** or **Delegate to Enterprise Teams/Apps** | (Depends on whether you have enabled enterprise teams mode.) Explicitly configured. **Does not follow** the default availability policy at the enterprise level. However, if delegated to organizations, **will follow** the organization-level default availability policy _for each organization that does not explicitly configure the model_. +**Delegate to organizations** or **Delegate to Enterprise Teams/Apps** | (Depends on whether you have enabled enterprise teams mode.) Explicitly configured. **Does not follow** the default availability policy at the enterprise level. However, if delegated to organizations, **will follow** the organization-level default availability policy _for each organization that does not explicitly configure the model_. ## How do I prevent default enablement? diff --git a/content/copilot/concepts/index.md b/content/copilot/concepts/index.md index 8ed9abdb3540..96c3672eb47e 100644 --- a/content/copilot/concepts/index.md +++ b/content/copilot/concepts/index.md @@ -6,10 +6,9 @@ versions: feature: copilot children: - /copilot-surfaces - - /agents - /agent-capabilities - /prompting-and-context - - /context + - /customizations - /models - /billing-and-usage - /security-governance-and-network-settings diff --git a/content/copilot/concepts/prompting-and-context/index.md b/content/copilot/concepts/prompting-and-context/index.md index 51af469c1b29..7f0478de63ae 100644 --- a/content/copilot/concepts/prompting-and-context/index.md +++ b/content/copilot/concepts/prompting-and-context/index.md @@ -7,6 +7,7 @@ versions: feature: copilot redirect_from: - /copilot/concepts/prompting + - /copilot/concepts/context children: - /prompt-engineering - /context-management diff --git a/content/copilot/get-started/where-to-use-github-copilot.md b/content/copilot/get-started/where-to-use-github-copilot.md index 3a141937fc8d..a50c9a0ba64c 100644 --- a/content/copilot/get-started/where-to-use-github-copilot.md +++ b/content/copilot/get-started/where-to-use-github-copilot.md @@ -74,7 +74,7 @@ Your choices hold across the workflow, including: * **Which model**: Different models suit different kinds of work, and you can switch models for chat and agents. See [AUTOTITLE](/copilot/how-tos/use-ai-models/change-the-chat-model). * **Which agents**: {% data variables.product.prodname_copilot_short %} agents and agents from other providers work in the same repositories, open pull requests, and go through review. {% data variables.product.prodname_copilot_short %} applies the same security protections, mitigations, and limitations to third-party agents as it does to {% data variables.copilot.copilot_cloud_agent %}. See [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-cloud-agent) and [AUTOTITLE](/copilot/concepts/agent-capabilities/about-agents/about-third-party-coding-agents). -* **What {% data variables.product.prodname_copilot_short %} can see**: Custom instructions, agent skills, and MCP servers connect {% data variables.product.prodname_copilot_short %} to your conventions and to the tools your team uses. See [AUTOTITLE](/copilot/concepts/context/mcp). +* **What {% data variables.product.prodname_copilot_short %} can see**: Custom instructions, agent skills, and MCP servers connect {% data variables.product.prodname_copilot_short %} to your conventions and to the tools your team uses. See [AUTOTITLE](/copilot/concepts/customizations/mcp). * **What {% data variables.product.prodname_copilot_short %} remembers**: For supported features, {% data variables.copilot.copilot_memory %} can reuse repository facts and your preferences in later work. See [AUTOTITLE](/copilot/concepts/prompting-and-context/copilot-memory). For organizations, administrator policies apply across most surfaces developers use. See [AUTOTITLE](/copilot/how-tos/administer-copilot). diff --git a/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/enable-copilot-cloud-agent.md b/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/enable-copilot-cloud-agent.md index d768c39b671e..df71a0d48b61 100644 --- a/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/enable-copilot-cloud-agent.md +++ b/content/copilot/how-tos/administer-copilot/manage-for-enterprise/manage-agents/enable-copilot-cloud-agent.md @@ -43,7 +43,7 @@ You may want to run a trial before enabling {% data variables.copilot.copilot_cl ## Enabling MCP servers -{% data variables.copilot.copilot_cloud_agent %} automatically has access to a small number of default MCP servers. See [AUTOTITLE](/copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent#default-mcp-servers). +{% data variables.copilot.copilot_cloud_agent %} automatically has access to a small number of default MCP servers. See [AUTOTITLE](/copilot/concepts/customizations/mcp#default-mcp-servers). You can enable third-party MCP servers to allow developers to integrate {% data variables.copilot.copilot_cloud_agent %} with other services in your DevOps toolchain, such as error-tracking platforms or logging systems. diff --git a/content/copilot/how-tos/administer-copilot/manage-for-organization/prepare-for-custom-agents.md b/content/copilot/how-tos/administer-copilot/manage-for-organization/prepare-for-custom-agents.md index 7a1e831bed7d..60ca335cbf03 100644 --- a/content/copilot/how-tos/administer-copilot/manage-for-organization/prepare-for-custom-agents.md +++ b/content/copilot/how-tos/administer-copilot/manage-for-organization/prepare-for-custom-agents.md @@ -15,7 +15,7 @@ category: ## Prerequisites -You should understand what {% data variables.copilot.copilot_custom_agents %} are and how they work. See [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +You should understand what {% data variables.copilot.copilot_custom_agents %} are and how they work. See [AUTOTITLE](/copilot/concepts/customizations/custom-agents). > [!NOTE] > If your organization is part of an enterprise, enterprise owners can configure a ruleset that restricts {% data variables.copilot.custom_agents_short %}. Contact your enterprise owners to check whether you can create and manage organization-level {% data variables.copilot.custom_agents_short %}. diff --git a/content/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers.md b/content/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers.md index d5a0d98ebc36..36152901cf52 100644 --- a/content/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers.md +++ b/content/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers.md @@ -13,7 +13,7 @@ docsTeamMetrics: - copilot-cli --- -The Model Context Protocol (MCP) is an open standard that defines how applications share context with large language models (LLMs). You can connect MCP servers to {% data variables.copilot.copilot_cli %} to give {% data variables.product.prodname_copilot_short %} access to external tools, data sources, and services. For an overview of MCP, see [AUTOTITLE](/copilot/concepts/context/mcp). +The Model Context Protocol (MCP) is an open standard that defines how applications share context with large language models (LLMs). You can connect MCP servers to {% data variables.copilot.copilot_cli %} to give {% data variables.product.prodname_copilot_short %} access to external tools, data sources, and services. For an overview of MCP, see [AUTOTITLE](/copilot/concepts/customizations/mcp). ## Adding an MCP server @@ -205,6 +205,13 @@ If your organization has configured a custom MCP registry URL, `/mcp search` con 1. Press Ctrl+S to save. The server is added to your `mcp-config.json` and started immediately. +## Using agent finder + +Agent finder searches a catalog of capabilities, including MCP servers, tools, agents, and skills. To make it available in the CLI: + +1. Download the [agent finder skill](https://github.com/ards-project/connectors/blob/main/skills/github-copilot/SKILL.md). +1. Add the skill to your `~/.copilot/skills` directory. For skill directory structure and installation guidance, see [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/add-skills). + ## Managing MCP servers You can manage your configured MCP servers using the `/mcp` commands in interactive mode or the `copilot mcp` subcommands from the terminal. @@ -271,6 +278,6 @@ Once you have added an MCP server, {% data variables.product.prodname_copilot_sh ## Further reading -* [AUTOTITLE](/copilot/concepts/context/mcp) +* [AUTOTITLE](/copilot/concepts/customizations/mcp) * [AUTOTITLE](/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp) * [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers) diff --git a/content/copilot/how-tos/copilot-cli/customize-copilot/add-skills.md b/content/copilot/how-tos/copilot-cli/customize-copilot/add-skills.md index 8027a419c12b..2ec42d4875c3 100644 --- a/content/copilot/how-tos/copilot-cli/customize-copilot/add-skills.md +++ b/content/copilot/how-tos/copilot-cli/customize-copilot/add-skills.md @@ -57,4 +57,4 @@ The `/skills` commands above run inside an interactive session. The same list, a {% data reusables.copilot.skills-compared %} -To learn more about how skills differ from other customization features, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/comparing-cli-features). +To learn more about how skills differ from other customization features, see [AUTOTITLE](/copilot/concepts/customizations/comparing-customizations). diff --git a/content/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli.md b/content/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli.md index 2b2deb263c64..6d2e3dececd9 100644 --- a/content/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli.md +++ b/content/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli.md @@ -20,9 +20,9 @@ docsTeamMetrics: When you prompt {% data variables.product.prodname_copilot_short %} to carry out a task it may choose to use one of your {% data variables.copilot.custom_agents_short %}, if {% data variables.product.prodname_copilot_short %} determines that the agent's expertise is a good fit for the task. -Work performed by a {% data variables.copilot.copilot_custom_agent_short %} is carried out using a subagent, which is a temporary agent spun up to complete the task. The subagent has its own context window, which can be populated by information that is not relevant to the main agent. In this way, especially for larger tasks, parts of the work can be offloaded to {% data variables.copilot.custom_agents_short %}, without cluttering the main agent's context window. The main agent can then focus on higher-level planning and coordination. +When the main agent delegates work to a {% data variables.copilot.copilot_custom_agent_short %}, that work is carried out by a subagent with its own context window. This lets the specialist focus on its assigned task without cluttering the main agent's context. You can also select a {% data variables.copilot.copilot_custom_agent_short %} for the session directly. -For more information, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents). +For more information, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents). ## Creating a {% data variables.copilot.copilot_custom_agent_short %} @@ -98,7 +98,7 @@ Each {% data variables.copilot.copilot_custom_agent_short %} is defined by a Mar Enter `/agent` in interactive mode and choose from the list of available {% data variables.copilot.custom_agents_short %}. Then enter a prompt that will be passed to the selected agent. > [!NOTE] - > The CLI's default agents are not included in this list. For more information about the default agents, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents#built-in-agents). + > The CLI's default agents are not included in this list. For more information about the default agents, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents#built-in-agents). * **Explicit instruction** @@ -160,7 +160,7 @@ For more information, including how this setting interacts with the `--no-custom ## Further reading -* [AUTOTITLE](/copilot/concepts/agents/copilot-cli/comparing-cli-features) +* [AUTOTITLE](/copilot/concepts/customizations/comparing-customizations) * [AUTOTITLE](/copilot/reference/custom-agents-configuration) * [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference#custom-agents-reference) * [AUTOTITLE](/copilot/tutorials/customization-library/custom-agents)—a curated collection of examples diff --git a/content/copilot/how-tos/copilot-cli/customize-copilot/overview.md b/content/copilot/how-tos/copilot-cli/customize-copilot/overview.md index 7c8b8f00485d..6fc12d63adc5 100644 --- a/content/copilot/how-tos/copilot-cli/customize-copilot/overview.md +++ b/content/copilot/how-tos/copilot-cli/customize-copilot/overview.md @@ -57,7 +57,7 @@ The Model Context Protocol (MCP) allows you to add external tools and data sourc * Book tickets online * Integrate with a calendar application -For more information, see [AUTOTITLE](/copilot/concepts/context/mcp). +For more information, see [AUTOTITLE](/copilot/concepts/customizations/mcp). ## Plugins diff --git a/content/copilot/how-tos/copilot-cli/index.md b/content/copilot/how-tos/copilot-cli/index.md index f0d4cd6d4597..635b48c80bdd 100644 --- a/content/copilot/how-tos/copilot-cli/index.md +++ b/content/copilot/how-tos/copilot-cli/index.md @@ -5,6 +5,7 @@ intro: Use {% data variables.product.prodname_copilot_short %} directly from you versions: feature: copilot redirect_from: + - /copilot/concepts/agents/copilot-cli - /copilot/github-copilot-in-the-cli - /copilot/github-copilot-in-the-cli/configuring-github-copilot-in-the-cli - /copilot/github-copilot-in-the-cli/using-github-copilot-in-the-cli @@ -37,20 +38,20 @@ children: - /automate-copilot-cli/quickstart - /automate-copilot-cli/run-cli-programmatically - /automate-copilot-cli/schedule-prompts - - /content/copilot/concepts/agents/about-agent-skills - - /content/copilot/concepts/agents/about-plugins + - /content/copilot/concepts/customizations/agent-skills + - /content/copilot/concepts/customizations/plugins - /content/copilot/concepts/copilot-surfaces/copilot-cli - /content/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/dynamic-workflows - - /content/copilot/concepts/agents/copilot-cli/about-custom-agents + - /content/copilot/concepts/customizations/custom-agents - /content/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/about-remote-control - - /content/copilot/concepts/agents/copilot-cli/comparing-cli-features + - /content/copilot/concepts/customizations/comparing-customizations - /content/copilot/concepts/prompting-and-context/context-management - /content/copilot/concepts/agent-capabilities/agent-powered-workflows-and-operations/tool-search - /content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/delegating-and-parallelizing-work-with-agents - - /content/copilot/concepts/agents/copilot-cli/lsp-servers + - /content/copilot/concepts/customizations/lsp-servers - /use-copilot-cli/research-with-copilot-cli - /content/copilot/concepts/agent-capabilities/choosing-and-delegating-agent-work/getting-a-second-opinion - - /content/copilot/concepts/agents/copilot-cli/about-cli-extensions + - /content/copilot/concepts/customizations/extensions - /content/copilot/how-tos/use-copilot-agents/use-dynamic-workflows - /content/copilot/reference/copilot-cli-reference/acp-server - /content/copilot/reference/copilot-cli-reference/cli-command-reference diff --git a/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers.md b/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers.md index f9e6e4cd37fc..838a570370f3 100644 --- a/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers.md +++ b/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/add-lsp-servers.md @@ -14,7 +14,7 @@ category: ## Introduction -This article explains how to add LSP servers for {% data variables.copilot.copilot_cli_short %}. For conceptual information about LSP servers, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/lsp-servers). +This article explains how to add LSP servers for {% data variables.copilot.copilot_cli_short %}. For conceptual information about LSP servers, see [AUTOTITLE](/copilot/concepts/customizations/lsp-servers). Adding an LSP server for {% data variables.copilot.copilot_cli_short %} is a two-step process: diff --git a/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/configure-toolsets.md b/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/configure-toolsets.md index 49aa5605ca81..a068aec818bf 100644 --- a/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/configure-toolsets.md +++ b/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/configure-toolsets.md @@ -22,7 +22,7 @@ The {% data variables.product.github %} MCP server includes default toolsets (`r * **Accessing remote-only toolsets** such as `copilot` (for {% data variables.copilot.copilot_cloud_agent %}) and `github_support_docs_search`, which are only available on the remote MCP server * **Selecting specific tools** for granular control when you want to exclude specific tools or combine toolsets with individual tools -For a complete list of available toolsets, see [Tools](https://github.com/github/github-mcp-server/blob/main/README.md#tools) in the `github/github-mcp-server` repository. For configuration examples, see [Server configuration](https://github.com/github/github-mcp-server/blob/main/docs/server-configuration.md). For a full introduction to the {% data variables.product.github %} MCP server and an overview of MCP, see [AUTOTITLE](/copilot/concepts/context/mcp). +For a complete list of available toolsets, see [Tools](https://github.com/github/github-mcp-server/blob/main/README.md#tools) in the `github/github-mcp-server` repository. For configuration examples, see [Server configuration](https://github.com/github/github-mcp-server/blob/main/docs/server-configuration.md). For a full introduction to the {% data variables.product.github %} MCP server and an overview of MCP, see [AUTOTITLE](/copilot/concepts/customizations/mcp). ## Configuring toolsets for the remote MCP server diff --git a/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp.md b/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp.md index 2d1a5ecc3cdb..083500b6c744 100644 --- a/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp.md +++ b/content/copilot/how-tos/copilot-in-your-ide/customize-copilot/extend-copilot-with-tools-and-context/extend-copilot-chat-with-mcp.md @@ -22,7 +22,7 @@ category: ## Introduction -The Model Context Protocol (MCP) is an open standard that defines how applications share context with large language models (LLMs). For an overview of MCP, see [AUTOTITLE](/copilot/concepts/context/mcp). +The Model Context Protocol (MCP) is an open standard that defines how applications share context with large language models (LLMs). For an overview of MCP, see [AUTOTITLE](/copilot/concepts/customizations/mcp). For a curated list of MCP servers from partners and the community, see the [{% data variables.product.github %} MCP Registry](https://github.com/mcp). diff --git a/content/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-custom-agents.md b/content/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-custom-agents.md index ffff1c7bcdfb..48bcb813506f 100644 --- a/content/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-custom-agents.md +++ b/content/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-custom-agents.md @@ -12,7 +12,7 @@ redirect_from: - /copilot/how-tos/use-copilot-agents/cloud-agent/create-custom-agents-in-your-ide --- -{% data variables.copilot.custom_agents_caps_short %} allow you to tailor {% data variables.product.prodname_copilot_short %}'s expertise for specific tasks. For a conceptual overview of {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +{% data variables.copilot.custom_agents_caps_short %} allow you to tailor {% data variables.product.prodname_copilot_short %}'s expertise for specific tasks. For a conceptual overview of {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents). {% data reusables.copilot.custom-agents-ide-preview %} diff --git a/content/copilot/how-tos/copilot-on-github/copilot-for-github-tasks/using-the-github-mcp-server-from-copilot-chat.md b/content/copilot/how-tos/copilot-on-github/copilot-for-github-tasks/using-the-github-mcp-server-from-copilot-chat.md index b939952d5a07..cb9ab5d09a02 100644 --- a/content/copilot/how-tos/copilot-on-github/copilot-for-github-tasks/using-the-github-mcp-server-from-copilot-chat.md +++ b/content/copilot/how-tos/copilot-on-github/copilot-for-github-tasks/using-the-github-mcp-server-from-copilot-chat.md @@ -14,7 +14,7 @@ redirect_from: The {% data variables.product.github %} MCP server is pre-configured in {% data variables.copilot.copilot_chat_dotcom_short %} with a limited set of skills, so you can use it immediately. Instruct {% data variables.copilot.copilot_chat_short %} to perform tasks like creating branches or merging pull requests on your behalf. -For a full list of available skills, see [AUTOTITLE](/copilot/reference/chat-cheat-sheet#mcp-skills). For more about MCP, see [AUTOTITLE](/copilot/concepts/context/mcp). +For a full list of available skills, see [AUTOTITLE](/copilot/reference/chat-cheat-sheet#mcp-skills). For more about MCP, see [AUTOTITLE](/copilot/concepts/customizations/mcp). ## Use the {% data variables.product.github %} MCP server diff --git a/content/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers.md b/content/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers.md index c68c600cff21..6beb3bdd4df6 100644 --- a/content/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers.md +++ b/content/copilot/how-tos/copilot-on-github/customize-copilot/configure-mcp-servers.md @@ -22,7 +22,7 @@ category: ## Prerequisite -Before setting up MCP servers for your repository, read [AUTOTITLE](/copilot/concepts/context/mcp) and [AUTOTITLE](/copilot/concepts/agents/cloud-agent/mcp-and-cloud-agent). +Before setting up MCP servers for your repository, read [AUTOTITLE](/copilot/concepts/customizations/mcp). ## Introduction diff --git a/content/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents.md b/content/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents.md index 4add7c99c6cc..1a3007b02a44 100644 --- a/content/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents.md +++ b/content/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents.md @@ -14,7 +14,7 @@ redirect_from: - /copilot/how-tos/use-copilot-agents/cloud-agent/create-custom-agents --- -{% data variables.copilot.custom_agents_caps_short %} allow you to tailor {% data variables.product.prodname_copilot_short %}'s expertise for specific tasks. For a conceptual overview of {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +{% data variables.copilot.custom_agents_caps_short %} allow you to tailor {% data variables.product.prodname_copilot_short %}'s expertise for specific tasks. For a conceptual overview of {% data variables.copilot.custom_agents_short %}, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents). {% data reusables.copilot.custom-agents-ide-preview %} diff --git a/content/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-teachers-and-os-maintainers.md b/content/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-teachers-and-os-maintainers.md index 3da40e15664a..36bea6e5cc16 100644 --- a/content/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-teachers-and-os-maintainers.md +++ b/content/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-teachers-and-os-maintainers.md @@ -32,7 +32,7 @@ There are two ways to qualify for free access to {% data variables.copilot.copil If you do not meet the previous criteria, you can do one of the following: -* Subscribe to [{% data variables.copilot.copilot_pro_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro), [{% data variables.copilot.copilot_pro_plus_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro), or [{% data variables.copilot.copilot_max_short %}](https://github.com/settings/billing/licensing?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=max) for a paid plan with access to premium models. +* Subscribe to [{% data variables.copilot.copilot_pro_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro), [{% data variables.copilot.copilot_pro_plus_short %}](https://github.com/github-copilot/signup?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=pro-plus), or [{% data variables.copilot.copilot_max_short %}](https://github.com/settings/billing/licensing?ref_product=copilot&ref_type=purchase&ref_style=text&ref_plan=max) for a paid plan with access to premium models. * Set up {% data variables.copilot.copilot_free_short %} to get a limited experience of {% data variables.product.prodname_copilot_short %} without a paid plan. See [AUTOTITLE](/copilot/get-started/plans). ## Accessing {% data variables.copilot.copilot_pro_short %} for free diff --git a/content/copilot/how-tos/github-copilot-app/customize-github-copilot-app.md b/content/copilot/how-tos/github-copilot-app/customize-github-copilot-app.md index 2e7ea8abdac0..4fb1719aa428 100644 --- a/content/copilot/how-tos/github-copilot-app/customize-github-copilot-app.md +++ b/content/copilot/how-tos/github-copilot-app/customize-github-copilot-app.md @@ -75,7 +75,7 @@ Use the agent picker dropdown in the prompt box to select a {% data variables.co Alternatively, type `/agent` in the prompt box to choose and invoke a {% data variables.copilot.copilot_custom_agent_short %}. -For more information, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +For more information, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents). ## Adding plugins diff --git a/content/copilot/how-tos/use-copilot-agents/cloud-agent/index.md b/content/copilot/how-tos/use-copilot-agents/cloud-agent/index.md index 0bc086be4327..ec241a511954 100644 --- a/content/copilot/how-tos/use-copilot-agents/cloud-agent/index.md +++ b/content/copilot/how-tos/use-copilot-agents/cloud-agent/index.md @@ -30,4 +30,4 @@ redirect_from: contentType: how-tos --- -These articles provide how-to information for using {% data variables.copilot.copilot_cloud_agent %}. For an overview of {% data variables.copilot.copilot_cloud_agent %}, see the articles under [AUTOTITLE](/copilot/concepts/agents/cloud-agent). +These articles provide how-to information for using {% data variables.copilot.copilot_cloud_agent %}. For an overview of {% data variables.copilot.copilot_cloud_agent %}, see [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-on-github). diff --git a/content/copilot/reference/copilot-billing/request-based-billing-legacy/github-copilot-premium-requests.md b/content/copilot/reference/copilot-billing/request-based-billing-legacy/github-copilot-premium-requests.md index cd7fd05dc469..18edd3c3cb95 100644 --- a/content/copilot/reference/copilot-billing/request-based-billing-legacy/github-copilot-premium-requests.md +++ b/content/copilot/reference/copilot-billing/request-based-billing-legacy/github-copilot-premium-requests.md @@ -72,7 +72,7 @@ If you run out of free minutes or premium requests, and you have _not_ set up bi {% data variables.copilot.copilot_cloud_agent %} uses a dedicated {% data variables.copilot.copilot_cloud_agent %} premium request SKU. This SKU still pulls from your monthly allowance of premium requests, but allows for more granular budget control and monitoring. -For more information about {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_custom_agents %}, see [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-on-github) and [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +For more information about {% data variables.copilot.copilot_cloud_agent %} and {% data variables.copilot.copilot_custom_agents %}, see [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-on-github) and [AUTOTITLE](/copilot/concepts/customizations/custom-agents). ## Using more than your included premium requests 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 ab98192e8121..f199be6f4fdd 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md @@ -539,7 +539,7 @@ These are the slash commands you can use from within an interactive CLI session. |-----------------------------------------------------|---------| | `/add-dir PATH` | Allow file access to a directory and load its `.github/skills` and `.github/agents` as trusted configurations. When sandboxing is enabled, also grants the sandbox access to the directory for the current session. | | `/after [DELAY PROMPT]`, `/after` | Schedule a non-recurring prompt, skill, or schedulable slash command for the current session (for example, `/after 30m remind me the time` or `/after 1h /chronicle standup`). With no arguments the schedule manager is displayed. {% data reusables.copilot.experimental %} | -| `/agent` | Browse and select from available agents (if any). See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents). | +| `/agent` | Browse and select from available agents (if any). See [AUTOTITLE](/copilot/concepts/customizations/custom-agents). | | `/app` | Open the current session in the {% data variables.copilot.github_copilot_app %} (requires version 1.1.3 or later), or show the download URL if the app is not installed. | | `/ask [QUESTION]`, `/btw [QUESTION]` | Ask a quick side question without adding to the conversation history. The response renders as Markdown. In the answer dialog, press Ctrl+E to expand it and Ctrl+Y to copy the full answer. Enter the command without a question to reopen the last side question answer in the current session. See [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli/ask-a-side-question). | | `/allow-all [off\|auto\|show]`, `/yolo [off\|auto\|show]` | Enable all permissions (tools, paths, and URLs). This is an alias for `/permissions allow-all`; see the `/permissions` row for the canonical command and its subcommands. | @@ -666,7 +666,7 @@ Use `/collect-debug-logs [file|gist|share] [PATH]` to gather debug logs for trou | `--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. | | `--additional-mcp-config=JSON` | Add an MCP server for this session only. The server configuration can be supplied as a JSON string or a file path (prefix with `@`). A relative `@file` path resolves against the session working directory (the `--resume`, `--worktree`, or `-C` directory), regardless of option order. Augments the configuration from `~/.copilot/mcp-config.json`. Overrides any installed MCP server configuration with the same name. See [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers). | -| `--agent=AGENT` | Specify a {% data variables.copilot.copilot_custom_agent_short %} to use. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents). | +| `--agent=AGENT` | Specify a {% data variables.copilot.copilot_custom_agent_short %} to use. See [AUTOTITLE](/copilot/concepts/customizations/custom-agents). | | `--allow-all` | Enable all permissions (equivalent to `--allow-all-tools --allow-all-paths --allow-all-urls`). | | `--allow-all-mcp-server-instructions` | Include initialization instructions from all MCP servers in the system prompt. By default, only allowlisted server instructions are included up front; other servers' instructions are retrieved on demand. | | `--allow-all-paths` | Disable file path verification and allow access to any path. | @@ -1344,6 +1344,32 @@ Installing a directory registers it as a custom skill source rather than copying Commands are an alternative to skills stored as individual `.md` files in `.claude/commands/`. The command name is derived from the filename. Command files use a simplified format (no `name` field required) and support `argument-hint`, `description`, `allowed-tools`, and `disable-model-invocation`. Commands have lower priority than skills with the same name. +## Extension modes + +{% data reusables.copilot.copilot-cli.cli-extensions-experimental %} + +In an interactive session, `/extensions mode` controls whether extensions run and whether {% data variables.product.prodname_copilot_short %} can manage them. + +| Mode | Extensions run | Agent can manage extensions | +| --- | --- | --- | +| **Load & Augment** (default) | Yes | Yes | +| **Load Only** | Yes | No | +| **Disabled** | No | No | + +In **Load & Augment** mode, the agent has tools to list discovered extensions, inspect their status and logs, scaffold a starter extension, and reload extensions after code changes. This lets the agent create and load extension code as part of your request. + +Choose **Load Only** to run an existing set of trusted extensions without giving the agent extension-management tools. The agent can still call tools supplied by running extensions. + +Mode changes take effect immediately in the current session: + +* Switching to **Disabled** stops running extension processes and removes their tools. +* Switching from **Disabled** to either loading mode starts extensions. +* Switching between **Load Only** and **Load & Augment** changes access to extension-management tools without stopping the extensions. + +Disabling extensions persists for future sessions until you choose a loading mode. Other sessions that are already running are not affected. + +To inspect extensions and their status, use `/extensions manage`. For discovery locations and implementation examples, see [AUTOTITLE](/copilot/tutorials/create-an-extension). + ## Custom agents reference Custom agents are specialized AI agents defined in Markdown files. For user, project, and added-root agents, the agent ID is derived from the file's path relative to the `agents` directory. The CLI removes the `.agent.md` or `.md` extension and replaces directory separators with `--`. For example, `agents/team/reviewer.agent.md` has the ID `team--reviewer`. diff --git a/content/copilot/reference/customization-cheat-sheet.md b/content/copilot/reference/customization-cheat-sheet.md index 7ecec9cc6eae..d542a89806f8 100644 --- a/content/copilot/reference/customization-cheat-sheet.md +++ b/content/copilot/reference/customization-cheat-sheet.md @@ -19,11 +19,11 @@ This table shows what each customization feature is and where it lives. |---------|-----------|-------------------| | [Custom instructions](/copilot/concepts/prompting-and-context/custom-instructions) | Always-on context that automatically applies to every interaction within its defined scope | `.github/copilot-instructions.md` (repo-wide), `.github/instructions/*.instructions.md` (path-specific), `AGENTS.md` (third-party agents), or personal/org settings via UI on {% data variables.product.github %} | | [Prompt files](/copilot/concepts/prompting-and-context/prompt-files) | Reusable, standalone prompt template with input variables | `.github/prompts/*.prompt.md` | -| [{% data variables.copilot.custom_agents_caps_short %}](/copilot/concepts/agents/cloud-agent/about-custom-agents) | Specialist persona with its own instructions, tool restrictions, and context | `.github/agents/AGENT-NAME.md` (repository), `/agents/AGENT-NAME.md` in the organization's `.github` or `.github-private` repository (org-level), `/agents/AGENT-NAME.md` in a designated `.github-private` repository (enterprise-level), or user profile | +| [AUTOTITLE](/copilot/concepts/customizations/custom-agents) | Specialist persona with its own instructions, tool restrictions, and context | `.github/agents/AGENT-NAME.md` (repository), `/agents/AGENT-NAME.md` in the organization's `.github` or `.github-private` repository (org-level), `/agents/AGENT-NAME.md` in a designated `.github-private` repository (enterprise-level), or user profile | | [{% data variables.copilot.subagents_caps_short %}](/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-subagents) | Separate agent spawned by the main agent to handle delegated work in an isolated context | N/A (runtime process, not a user-configured file) | | [Agent skills](/copilot/concepts/agents/about-agent-skills) | Folder of instructions, scripts, and resources that {% data variables.product.prodname_copilot_short %} loads when relevant to a task | `.github/skills//SKILL.md`, `.claude/skills//SKILL.md`, or `.agents/skills//SKILL.md` (project); `~/.copilot/skills//SKILL.md` or `~/.agents/skills//SKILL.md` (personal) | | [Hooks](/copilot/concepts/agents/hooks) | Custom shell commands that execute deterministically at specific points in an agent's workflow | `.github/hooks/*.json` | -| [MCP servers](/copilot/concepts/context/mcp) | Connection to external systems, APIs, and databases | `mcp.json` (path varies by IDE), repository MCP settings on {% data variables.product.github %} (applies to {% data variables.copilot.copilot_cloud_agent_short %} and {% data variables.copilot.copilot_code-review_short %}), or `mcp-servers` property in {% data variables.copilot.copilot_custom_agent_short %} configurations | +| [AUTOTITLE](/copilot/concepts/customizations/mcp) | Connection to external systems, APIs, and databases | `mcp.json` (path varies by IDE), repository MCP settings on {% data variables.product.github %} (applies to {% data variables.copilot.copilot_cloud_agent_short %} and {% data variables.copilot.copilot_code-review_short %}), or `mcp-servers` property in {% data variables.copilot.copilot_custom_agent_short %} configurations | ## Usage comparison @@ -33,11 +33,11 @@ This table helps you decide which customization feature to use. |---------|---------------|-------------|-------------------| | [Custom instructions](/copilot/concepts/prompting-and-context/custom-instructions) | Automatic | Standards, guidelines, or expectations that apply broadly across a context | Enforce coding standards, accessibility rules, review checklists | | [Prompt files](/copilot/concepts/prompting-and-context/prompt-files) | Manual: reference directly in chat or use the prompt file picker | Focused single tasks you run once with different inputs each time | Generate unit tests, run a code review checklist | -| [{% data variables.copilot.custom_agents_caps_short %}](/copilot/concepts/agents/cloud-agent/about-custom-agents) | Manual: select from the agent dropdown in your IDE, on {% data variables.product.github %}, or in {% data variables.copilot.copilot_cli_short %} | Projects or processes with distinct stages that need specialized capabilities or strict handoffs | React reviewer agent, read-only auditing agent | +| [AUTOTITLE](/copilot/concepts/customizations/custom-agents) | Manual: select from the agent dropdown in your IDE, on {% data variables.product.github %}, or in {% data variables.copilot.copilot_cli_short %} | Projects or processes with distinct stages that need specialized capabilities or strict handoffs | React reviewer agent, read-only auditing agent | | [{% data variables.copilot.subagents_caps_short %}](/copilot/how-tos/copilot-in-your-ide/use-copilot-agents/use-subagents) | Automatic, or reference a {% data variables.copilot.subagent_short %} directly in your prompt | Complex subtasks that should run in isolation from the main agent | Codebase research, running test suites | | [Agent skills](/copilot/concepts/agents/about-agent-skills) | Automatic: chosen by {% data variables.product.prodname_copilot_short %} when relevant to your prompt | Multi-step workflows with bundled assets that should be loaded as needed | {% data variables.product.prodname_actions %} failure debugging, deployment procedures, release note drafting | | [Hooks](/copilot/concepts/agents/hooks) | Automatic: at configured lifecycle events | Tasks that need to run at a specific point in the agent lifecycle, with guaranteed execution | Run a formatter after every file edit, approve or deny tool executions, prevent credential leaks with {% data variables.product.prodname_secret_scanning %} | -| [MCP servers](/copilot/concepts/context/mcp) | Automatic, or ask for a specific tool by name | Tasks that require access to external tools or real-time data | Manage issues and PRs ({% data variables.product.github %} MCP server), automate browser testing (Playwright MCP server) | +| [AUTOTITLE](/copilot/concepts/customizations/mcp) | Automatic, or ask for a specific tool by name | Tasks that require access to external tools or real-time data | Manage issues and PRs ({% data variables.product.github %} MCP server), automate browser testing (Playwright MCP server) | ## IDE and surface support diff --git a/content/copilot/reference/github-copilot-app-reference/built-in-skills.md b/content/copilot/reference/github-copilot-app-reference/built-in-skills.md index c6577c60ca1d..cd6a46401469 100644 --- a/content/copilot/reference/github-copilot-app-reference/built-in-skills.md +++ b/content/copilot/reference/github-copilot-app-reference/built-in-skills.md @@ -19,7 +19,7 @@ Some built-in skills are available as slash commands. When available in your cur | Skill ID | When to use | | --- | --- | -| `af` | Find installable MCP servers, tools, skills, and agents by searching ARD Agent Finder. Invoke this skill with `/af`. See [AUTOTITLE](/copilot/concepts/context/mcp#agent-finder). | +| `af` | Find installable MCP servers, tools, skills, and agents by searching ARD Agent Finder. Invoke this skill with `/af`. See [AUTOTITLE](/copilot/concepts/customizations/mcp#agent-finder). | | `agent-merge` | Follow up on review comments, failing checks, and merge conflicts after agent merge is enabled for a pull request. The agent merge workflow invokes this skill automatically. See [AUTOTITLE](/copilot/how-tos/github-copilot-app/managing-issues-and-pull-requests#merging-a-pull-request). | | `create-canvas` | Create and troubleshoot canvas extensions in the app side panel, including actions, inputs, rendered content, and setup. Invoke this skill with `/create-canvas`. See [AUTOTITLE](/copilot/how-tos/github-copilot-app/working-with-canvas-extensions). | | `orchestrate` | Coordinate work across sessions and repositories by creating and guiding child sessions. Invoke this skill with `/orchestrate`. | diff --git a/content/copilot/reference/github-copilot-app-reference/slash-commands.md b/content/copilot/reference/github-copilot-app-reference/slash-commands.md index f30067d240b1..afe288401b70 100644 --- a/content/copilot/reference/github-copilot-app-reference/slash-commands.md +++ b/content/copilot/reference/github-copilot-app-reference/slash-commands.md @@ -26,8 +26,8 @@ Some commands require specific context, such as an active session, session chang | Slash command | What it does | | --- | --- | -| `/af` | Finds installable MCP servers, tools, skills, and agents by searching Agent Finder. This slash command is a built-in skill. See [AUTOTITLE](/copilot/concepts/context/mcp#agent-finder). | -| `/agent` | Selects a {% data variables.copilot.copilot_custom_agent_short %} for the session. See [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). | +| `/af` | Finds installable MCP servers, tools, skills, and agents by searching Agent Finder. This slash command is a built-in skill. See [AUTOTITLE](/copilot/concepts/customizations/mcp#agent-finder). | +| `/agent` | Selects a {% data variables.copilot.copilot_custom_agent_short %} for the session. See [AUTOTITLE](/copilot/concepts/customizations/custom-agents). | | `/allow-all-tools` or `/yolo` | **Requires an active session.** Turns tool auto-approval on or shows its current state. | | `/attach-files` | Opens a file picker and attaches files to your message. | | `/attach-folder` | Opens a folder picker and attaches a folder to your message. | diff --git a/content/copilot/reference/hooks-reference.md b/content/copilot/reference/hooks-reference.md index 03ce5d75cc48..0be7a2c68978 100644 --- a/content/copilot/reference/hooks-reference.md +++ b/content/copilot/reference/hooks-reference.md @@ -936,4 +936,4 @@ Behavior depends on where you set the flag: * [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/use-hooks) * [AUTOTITLE](/copilot/reference/hooks-reference) * [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference) -* [AUTOTITLE](/copilot/concepts/agents/cloud-agent) +* [AUTOTITLE](/copilot/concepts/copilot-surfaces/copilot-on-github) diff --git a/content/copilot/tutorials/create-an-extension.md b/content/copilot/tutorials/create-an-extension.md index b1b540e4d66d..a18027bbcc17 100644 --- a/content/copilot/tutorials/create-an-extension.md +++ b/content/copilot/tutorials/create-an-extension.md @@ -22,7 +22,7 @@ In this tutorial, you'll build two simple extensions as examples of what you can * A tool, called `tool-time`, that {% data variables.product.prodname_copilot_short %} can call to report how long its tool calls have taken so far in a session. * A slash command, called `/tokencount`, that reports how many tokens you've used since you started counting. -Both examples rely only on the SDK that's bundled with the {% data variables.copilot.copilot_cli_short %}, so there's nothing extra to install. For background on how extensions work, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-cli-extensions). +Both examples rely only on the SDK that's bundled with the {% data variables.copilot.copilot_cli_short %}, so there's nothing extra to install. For background on how extensions work, see [AUTOTITLE](/copilot/concepts/customizations/extensions). > [!WARNING] > Extensions execute on your computer with your privileges. Only load extension code that you trust, in the same way you would only run any other script you didn't write yourself. @@ -34,6 +34,22 @@ Both examples rely only on the SDK that's bundled with the {% data variables.cop * **JavaScript**: Extensions are written in JavaScript, so you'll need to be familiar with this language to create your own extensions. * **A repository**: The second example adds a project-level extension, so you'll need a local copy of a Git repository in which to add the extension. +## Choosing an extension location + +Each CLI extension lives in a named directory containing an entry file called `extension.mjs`, `extension.cjs`, or `extension.js`. The directory name becomes the extension name. The CLI runs the entry file directly with Node.js, so write it in JavaScript rather than TypeScript. + +| Source | Location | Availability | +| --- | --- | --- | +| Project | `.github/extensions/NAME/` in the current repository | Sessions working in that repository | +| User | `~/.copilot/extensions/NAME/` | Your CLI sessions across directories | +| Plugin | An installed plugin | Wherever the plugin is enabled | + +Use a project extension to share project-specific functionality with collaborators. Use a user extension for personal functionality across projects. Both use the same directory structure, so you can share a personal extension by moving its directory into a repository's `.github/extensions/` directory. + +Extensions must be enabled before they can run. You can start the CLI with `--experimental`, as the examples below do, or run `/experimental on` in an existing interactive session. + +For controls over loading extensions and letting the agent manage them, see [Extension modes](/copilot/reference/copilot-cli-reference/cli-command-reference#extension-modes). + ## Example extension 1: A "tool time" tool This example adds a **user-level** extension called `tool-time`. It adds a new tool—called `session_tool_time`—that {% data variables.product.prodname_copilot_short %} can call to report how long tool calls have taken so far this session, and how many calls that covers. diff --git a/content/copilot/tutorials/customization-library/custom-agents/your-first-custom-agent.md b/content/copilot/tutorials/customization-library/custom-agents/your-first-custom-agent.md index 5b4d58717cc2..bddb5c72c242 100644 --- a/content/copilot/tutorials/customization-library/custom-agents/your-first-custom-agent.md +++ b/content/copilot/tutorials/customization-library/custom-agents/your-first-custom-agent.md @@ -20,7 +20,7 @@ contentType: tutorials {% data variables.copilot.custom_agents_caps_short %} are specialized versions of {% data variables.copilot.copilot_cloud_agent %} that maintain consistent expertise across entire workflows. Unlike custom instructions that apply broadly, or prompt files for one-time tasks, {% data variables.copilot.custom_agents_short %} are selected for specific tasks and maintain their configuration throughout the workflow. -For a more in-depth overview, see [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents). +For a more in-depth overview, see [AUTOTITLE](/copilot/concepts/customizations/custom-agents). ## Your first {% data variables.copilot.copilot_custom_agent_short %} diff --git a/content/get-started/start-your-journey/deploying-your-website-automatically.md b/content/get-started/start-your-journey/deploying-your-website-automatically.md index 02554b5ce38b..696541f7c53a 100644 --- a/content/get-started/start-your-journey/deploying-your-website-automatically.md +++ b/content/get-started/start-your-journey/deploying-your-website-automatically.md @@ -124,6 +124,6 @@ Across this series, you built a complete software project and practiced the {% d * Expand your understanding of Git and {% data variables.product.github %}. For more information, see [AUTOTITLE](/get-started/start-your-journey/git-and-github-learning-resources). * Explore {% data variables.copilot.copilot_chat_short %} to learn faster and get help as you code. For more information, see [AUTOTITLE]({% ifversion ghes %}/enterprise-cloud@latest{% endif %}/copilot/concepts/chat){% ifversion ghes %} in the {% data variables.product.prodname_ghe_cloud %} documentation{% endif %}. -* Go deeper with AI and learn how agents can act like a practical coding partner by turning ideas into small actionable steps, generating examples, and handling repetitive work. For more information, see [AUTOTITLE]({% ifversion ghes %}/enterprise-cloud@latest{% endif %}/copilot/concepts/agents){% ifversion ghes %} in the {% data variables.product.prodname_ghe_cloud %} documentation{% endif %}. +* Go deeper with AI and learn how agents can act like a practical coding partner by turning ideas into small actionable steps, generating examples, and handling repetitive work. For more information, see [AUTOTITLE]({% ifversion ghes %}/enterprise-cloud@latest{% endif %}/copilot/concepts/agent-capabilities){% ifversion ghes %} in the {% data variables.product.prodname_ghe_cloud %} documentation{% endif %}. * Learn more about automating your software projects with {% data variables.product.prodname_actions %} workflows. For more information, see [AUTOTITLE](/actions/get-started/understand-github-actions). * Add a custom domain or explore more ways to publish your website with {% data variables.product.prodname_pages %}. For more information, see [AUTOTITLE](/pages/getting-started-with-github-pages). diff --git a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/converting-branch-protections-to-rulesets.md b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/converting-branch-protections-to-rulesets.md index aa76e62c1048..e4ce2ab0237e 100644 --- a/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/converting-branch-protections-to-rulesets.md +++ b/content/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/converting-branch-protections-to-rulesets.md @@ -14,11 +14,40 @@ category: Rulesets give you clearer visibility and control over how protections apply to a repository. Unlike branch protection rules, multiple rulesets can apply to the same branch at the same time, and people with read access can view the active rulesets. This helps developers understand the rules that affect them and lets auditors review repository protections without administrator access. -To move your existing protections to this model, convert one branch protection rule at a time in a guided flow. {% data variables.product.github %} generates one or more rulesets that preserve the original rule's behavior. You can preview the rulesets{% ifversion repo-rules-enterprise %}, choose how each one is enforced,{% endif %} and verify the result before you remove the original branch protection rule. +{% ifversion branch-protection-ruleset-bulk-conversion %}You can import eligible branch protection rules together from the repository's ruleset settings, or convert one rule at a time.{% endif %} + +{% data variables.product.github %} proposes one or more rulesets for each branch protection rule. Before creating the rulesets, you can review their names and any warnings about changes in behavior. One branch protection rule can produce multiple rulesets when its protections cannot be represented in a single ruleset. For more information about rulesets, see [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets). -## Converting a branch protection rule to a ruleset +{% ifversion branch-protection-ruleset-bulk-conversion %} + +## Converting branch protection rules for a repository + +You can convert multiple eligible branch protection rules. Before creating the rulesets, you can review and configure which protections will be imported and how the new rulesets will be enforced. + +{% data reusables.repositories.navigate-to-repo %} +{% data reusables.repositories.sidebar-settings %} +{% data reusables.repositories.repo-rulesets-settings %} +1. At the top of the "Rulesets" page, click **Import branch protection rules**. +1. In the "Review import" dialog, review the proposed rulesets: + * If a protection is labeled **Already covered by an existing ruleset**, the import will not create another ruleset for it. + * Review any warnings about new behavior. A branch protection rule can result in multiple proposed rulesets. +1. From the **Enforcement status** dropdown, choose a status for the new rulesets. + * **Active**: Enforces the rulesets as soon as they are created. + * **Evaluate**: Records how the rulesets would behave without enforcing them. + * **Disabled**: Creates the rulesets without evaluating or enforcing them. +1. Select the checkbox for each proposed ruleset that you want to create. +1. Click **Create rulesets**. +1. In the "Creating ruleset" dialog that follows, choose what to do with the original branch protection rules. + * To retain the original protections, click **Keep rule**. The original rules continue to protect matching branches. An **Active** ruleset is enforced alongside them, so changes must satisfy both. + * To remove the original protections, click **Delete branch protection rule**. Only delete the original rules if the new rulesets are **Active** and you have confirmed that they cover the intended branches and behave as expected. **Evaluate** and **Disabled** rulesets do not provide active protection. + +{% endif %} + +## Converting a single branch protection rule to a ruleset + +{% ifversion branch-protection-ruleset-bulk-conversion %}Use the single-rule flow when you want to review and configure the conversion for one branch protection rule at a time.{% endif %} {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.sidebar-settings %} @@ -32,9 +61,6 @@ For more information about rulesets, see [AUTOTITLE](/repositories/configuring-b If you keep the original branch protection rule, it continues to protect matching branches. An **Active** ruleset is enforced alongside it, so changes must satisfy both.{% ifversion repo-rules-enterprise %} An **Evaluate** ruleset records how it would behave without enforcing its rules.{% endif %} -> [!NOTE] -> The conversion covers all branch protection types with the exception of the "Require conversation resolution before merging" setting. In branch protections, this setting exists on its own. In rulesets, conversation resolution is part of the pull request rule and only applies when that rule is enabled. As a result, this setting does not map one to one during conversion. See [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets). - {% ifversion repo-rules-enterprise %} ### Choosing an enforcement status diff --git a/data/features/branch-protection-ruleset-bulk-conversion.yml b/data/features/branch-protection-ruleset-bulk-conversion.yml new file mode 100644 index 000000000000..0536ae70062d --- /dev/null +++ b/data/features/branch-protection-ruleset-bulk-conversion.yml @@ -0,0 +1,5 @@ +# Reference: github/releases#10746 +# Import a repository's eligible branch protection rules as rulesets +versions: + ghec: '*' + ghes: '>=3.24' diff --git a/data/reusables/contributing/content-linter-rules.md b/data/reusables/contributing/content-linter-rules.md index e9a00f1331ad..1aee97d72608 100644 --- a/data/reusables/contributing/content-linter-rules.md +++ b/data/reusables/contributing/content-linter-rules.md @@ -69,7 +69,7 @@ | GHD065 | frontmatter-content-type | Content files in content-type directories must have a contentType frontmatter property that matches the parent directory. | error | frontmatter, content-type | | GHD066 | frontmatter-docs-team-metrics | Articles whose path contains a path-enforced docsTeamMetrics value must include that value in their docsTeamMetrics frontmatter property. | error | frontmatter, docs-team-metrics | | GHD067 | frontmatter-rest-api-category | Autogenerated REST API endpoint files must have a valid `category` frontmatter property | error | frontmatter, rest, category | -| [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | deprecated liquid syntax: octicon- | The octicon liquid syntax used is deprecated. Use this format instead `octicon "" aria-label=""` | error | | +| [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | deprecated liquid syntax: octicon-<icon-name> | The octicon liquid syntax used is deprecated. Use this format instead `octicon "" aria-label=""` | error | | | [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | deprecated liquid syntax: site.data | Catch occurrences of deprecated liquid data syntax. | error | | | [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | developer-domain | Catch occurrences of developer.github.com domain. | error | | | [search-replace](https://github.com/OnkarRuikar/markdownlint-rule-search-replace) | docs-domain | Catch occurrences of docs.github.com domain. | error | | diff --git a/data/reusables/copilot/auto-model-discount.md b/data/reusables/copilot/auto-model-discount.md index 6996f7520fd3..4b7fa3f3612c 100644 --- a/data/reusables/copilot/auto-model-discount.md +++ b/data/reusables/copilot/auto-model-discount.md @@ -1 +1,6 @@ -If you are on a paid {% data variables.product.prodname_copilot_short %} plan, you qualify for a 10% discount on model costs while using {% data variables.copilot.copilot_auto_model_selection_short %} in {% data variables.copilot.copilot_chat_short %}, {% data variables.copilot.copilot_cli_short %}, the {% data variables.copilot.github_copilot_app %}, or {% data variables.copilot.copilot_cloud_agent %}. +If you are on a paid {% data variables.product.prodname_copilot_short %} plan, you qualify for a 10% discount on model costs while using {% data variables.copilot.copilot_auto_model_selection_short %} in {% data variables.copilot.copilot_chat_short %}, {% data variables.copilot.copilot_cli_short %}, the {% data variables.copilot.github_copilot_app %}, or {% data variables.copilot.copilot_cloud_agent %}. + + +> [!NOTE] +> If you are on the {% data variables.copilot.copilot_max_short %} plan, you'll receive a 30% discount through October 28, 2026 while using {% data variables.copilot.copilot_auto_model_selection_short %}. + diff --git a/data/reusables/copilot/custom-agents-further-reading.md b/data/reusables/copilot/custom-agents-further-reading.md index 654c0665c969..0353bd25aa48 100644 --- a/data/reusables/copilot/custom-agents-further-reading.md +++ b/data/reusables/copilot/custom-agents-further-reading.md @@ -1,5 +1,5 @@ ## Further reading -* [AUTOTITLE](/copilot/concepts/agents/cloud-agent/about-custom-agents) +* [AUTOTITLE](/copilot/concepts/customizations/custom-agents) * [AUTOTITLE](/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/create-custom-agents) * [AUTOTITLE](/copilot/reference/custom-agents-configuration) diff --git a/data/reusables/copilot/mcp/about-github-mcp-server.md b/data/reusables/copilot/mcp/about-github-mcp-server.md index f2bd83727cb8..5bf86d9c44e6 100644 --- a/data/reusables/copilot/mcp/about-github-mcp-server.md +++ b/data/reusables/copilot/mcp/about-github-mcp-server.md @@ -2,4 +2,4 @@ The {% data variables.product.github %} MCP server is a Model Context Protocol (MCP) server provided and maintained by {% data variables.product.github %}. MCP allows you to integrate AI capabilities with other tools and services, enhancing your development experience by providing context-aware AI assistance. -For a full introduction to the {% data variables.product.github %} MCP server and an overview of MCP, see [AUTOTITLE](/copilot/concepts/context/mcp). +For a full introduction to the {% data variables.product.github %} MCP server and an overview of MCP, see [AUTOTITLE](/copilot/concepts/customizations/mcp). diff --git a/data/reusables/copilot/mcp/mcp-chat-in-ide.md b/data/reusables/copilot/mcp/mcp-chat-in-ide.md index a14b1fe1722e..ef0917ce1b13 100644 --- a/data/reusables/copilot/mcp/mcp-chat-in-ide.md +++ b/data/reusables/copilot/mcp/mcp-chat-in-ide.md @@ -1 +1 @@ -You can use MCP to extend the capabilities of {% data variables.copilot.copilot_chat_short %} by integrating it with a wide range of existing tools and services. For additional information, see [AUTOTITLE](/copilot/concepts/context/mcp). +You can use MCP to extend the capabilities of {% data variables.copilot.copilot_chat_short %} by integrating it with a wide range of existing tools and services. For additional information, see [AUTOTITLE](/copilot/concepts/customizations/mcp). diff --git a/data/reusables/repositories/rulesets-convert-branch-protection-rule.md b/data/reusables/repositories/rulesets-convert-branch-protection-rule.md index d3662e02d812..5b4c87c9ad4e 100644 --- a/data/reusables/repositories/rulesets-convert-branch-protection-rule.md +++ b/data/reusables/repositories/rulesets-convert-branch-protection-rule.md @@ -1 +1 @@ -{% ifversion branch-protection-ruleset-conversion %}To convert an existing branch protection rule to rulesets, see [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/converting-branch-protections-to-rulesets).{% endif %} +{% ifversion branch-protection-ruleset-conversion %}To convert branch protection rules to rulesets, see [AUTOTITLE](/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/converting-branch-protections-to-rulesets).{% endif %} diff --git a/data/reusables/rest-api/breaking-changes-changelog.md b/data/reusables/rest-api/breaking-changes-changelog.md index d445198ca3b1..1a54776e6cea 100644 --- a/data/reusables/rest-api/breaking-changes-changelog.md +++ b/data/reusables/rest-api/breaking-changes-changelog.md @@ -1975,6 +1975,12 @@ Version `2022-11-28` is the first version of the GitHub Enterprise Cloud REST AP +{% endif %} +{% if query.apiVersion == nil or "2022-11-28" <= query.apiVersion %} +## Version 2022-11-28 + +Version `2022-11-28` is the first version of the {% data variables.product.prodname_ghe_server %} REST API after date-based versioning was introduced. This version does not include any breaking changes. + {% endif %} {% endif %} @@ -2648,5 +2654,38 @@ Version `2022-11-28` is the first version of the GitHub Enterprise Cloud REST AP +{% endif %} +{% if query.apiVersion == nil or "2022-11-28" <= query.apiVersion %} +## Version 2022-11-28 + +Version `2022-11-28` is the first version of the {% data variables.product.prodname_ghe_server %} REST API after date-based versioning was introduced. This version does not include any breaking changes. + +{% endif %} +{% endif %} + +{% ifversion ghes = 3.20 %} +{% if query.apiVersion == nil or "2022-11-28" <= query.apiVersion %} +## Version 2022-11-28 + +Version `2022-11-28` is the first version of the {% data variables.product.prodname_ghe_server %} REST API after date-based versioning was introduced. This version does not include any breaking changes. + +{% endif %} +{% endif %} + +{% ifversion ghes = 3.19 %} +{% if query.apiVersion == nil or "2022-11-28" <= query.apiVersion %} +## Version 2022-11-28 + +Version `2022-11-28` is the first version of the {% data variables.product.prodname_ghe_server %} REST API after date-based versioning was introduced. This version does not include any breaking changes. + +{% endif %} +{% endif %} + +{% ifversion ghes = 3.18 %} +{% if query.apiVersion == nil or "2022-11-28" <= query.apiVersion %} +## Version 2022-11-28 + +Version `2022-11-28` is the first version of the {% data variables.product.prodname_ghe_server %} REST API after date-based versioning was introduced. This version does not include any breaking changes. + {% endif %} {% endif %} diff --git a/eslint.config.ts b/eslint.config.ts index 3aea131e7c70..db3e4e689651 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -46,6 +46,8 @@ export default [ typescript: true, node: true, }, + // Maps Primer components to DOM elements for the github and jsx-a11y rules + ...primerReact.configs.recommended.settings, }, plugins: { github, @@ -73,6 +75,10 @@ export default [ // TypeScript ESLint recommended rules ...tseslint.configs.recommended.rules, + // Primer React recommended extends plugin:github/react, which flat config does not apply. + // Keep before jsx-a11y recommended so its jsx-a11y rule settings win, as in the eslintrc extends order. + ...github.getFlatConfigs().react.rules, + // Primer React recommended rules ...primerReact.configs.recommended.rules, diff --git a/src/archives/README.md b/src/archives/README.md index 98f3f3148125..dc7220f47765 100644 --- a/src/archives/README.md +++ b/src/archives/README.md @@ -26,6 +26,7 @@ The system acts as a reverse proxy for specific URL paths. - `archived-asset-redirects.ts`: Maps legacy asset paths to modern equivalents where possible. - **`lib/`** - `is-archived-version.ts`: Utilities to parse URLs and check against the list of deprecated versions defined in `src/versions`. + - `archived-languages.ts`: Checks whether an archived version includes a given language. - **`scripts/`** - `warmup-remotejson.ts`: Utility to prime caches for remote JSON files. diff --git a/src/archives/lib/archived-languages.ts b/src/archives/lib/archived-languages.ts new file mode 100644 index 000000000000..d52fcfc2b128 --- /dev/null +++ b/src/archives/lib/archived-languages.ts @@ -0,0 +1,7 @@ +import { languages } from '@/languages/lib/languages' +import versionSatisfiesRange from '@/versions/lib/version-satisfies-range' + +export function isLanguageInArchivedVersion(language: string, version: string): boolean { + const firstArchivedVersion = languages[language]?.firstArchivedVersion + return !firstArchivedVersion || versionSatisfiesRange(version, `>=${firstArchivedVersion}`) +} diff --git a/src/archives/middleware/archived-enterprise-versions.ts b/src/archives/middleware/archived-enterprise-versions.ts index a96813a02b5d..6a4451cfdee6 100644 --- a/src/archives/middleware/archived-enterprise-versions.ts +++ b/src/archives/middleware/archived-enterprise-versions.ts @@ -12,6 +12,7 @@ import { import patterns from '@/frame/lib/patterns' import versionSatisfiesRange from '@/versions/lib/version-satisfies-range' import { isArchivedVersion } from '@/archives/lib/is-archived-version' +import { isLanguageInArchivedVersion } from '@/archives/lib/archived-languages' import { setFastlySurrogateKey, SURROGATE_ENUMS } from '@/frame/middleware/set-fastly-surrogate-key' import { readCompressedJsonFileFallbackLazily } from '@/frame/lib/read-json-file' import { archivedCacheControl, languageCacheControl } from '@/frame/middleware/cache-control' @@ -82,6 +83,14 @@ export default async function archivedEnterpriseVersions( const redirectCode = pathLanguagePrefixed(req.path) ? 301 : 302 if (deprecatedWithFunctionalRedirects.includes(requestedVersion)) { + if ( + req.context?.userLanguage && + !pathLanguagePrefixed(req.path) && + !isLanguageInArchivedVersion(req.context.userLanguage, requestedVersion) + ) { + // The archive lacks this language, so send unprefixed links to English instead of a 404. + req.context.userLanguage = 'en' + } const redirectTo = req.context ? getRedirect(req.path, req.context) : undefined if (redirectTo) { if (redirectCode === 302) { diff --git a/src/archives/tests/archived-languages.ts b/src/archives/tests/archived-languages.ts new file mode 100644 index 000000000000..6e7acaf3a460 --- /dev/null +++ b/src/archives/tests/archived-languages.ts @@ -0,0 +1,26 @@ +import { describe, expect, test } from 'vitest' + +import { isLanguageInArchivedVersion } from '@/archives/lib/archived-languages' + +describe('isLanguageInArchivedVersion', () => { + test('English exists in every archived version', () => { + expect(isLanguageInArchivedVersion('en', '2.13')).toBe(true) + expect(isLanguageInArchivedVersion('en', '3.0')).toBe(true) + }) + + test('languages added in 3.3 are missing from 3.0 through 3.2', () => { + for (const language of ['zh', 'ru', 'fr', 'ko', 'de']) { + expect(isLanguageInArchivedVersion(language, '3.0')).toBe(false) + expect(isLanguageInArchivedVersion(language, '3.2')).toBe(false) + expect(isLanguageInArchivedVersion(language, '3.3')).toBe(true) + expect(isLanguageInArchivedVersion(language, '3.17')).toBe(true) + } + }) + + test('languages added in 3.0 exist from 3.0 on', () => { + for (const language of ['es', 'ja', 'pt']) { + expect(isLanguageInArchivedVersion(language, '3.0')).toBe(true) + expect(isLanguageInArchivedVersion(language, '3.2')).toBe(true) + } + }) +}) diff --git a/src/article-api/middleware/pagelist.ts b/src/article-api/middleware/pagelist.ts index 19c43d42e72a..841ceddfc1b4 100644 --- a/src/article-api/middleware/pagelist.ts +++ b/src/article-api/middleware/pagelist.ts @@ -100,13 +100,12 @@ router.get( '/:someParam', pagelistValidationMiddleware as RequestHandler, catchMiddlewareError(async function (req: ExtendedRequest, res: Response) { - const { someParam } = req.params + // req.originalUrl keeps raw encodings like %40, so editing it in place can redirect to itself. + const queryStart = req.originalUrl.indexOf('?') + const query = queryStart === -1 ? '' : req.originalUrl.slice(queryStart) res.safeRedirect( 308, - req.originalUrl.replace( - `/pagelist/${someParam}`, - `/pagelist/${req.context!.currentLanguage}/${req.context!.currentVersion}`, - ), + `${req.baseUrl}/${req.context!.currentLanguage}/${req.context!.currentVersion}${query}`, ) }), ) diff --git a/src/article-api/templates/graphql-reference.template.md b/src/article-api/templates/graphql-reference.template.md index af16acd61d3d..1f054b5d8ff8 100644 --- a/src/article-api/templates/graphql-reference.template.md +++ b/src/article-api/templates/graphql-reference.template.md @@ -23,7 +23,7 @@ ### Arguments for `{{ item.name }}` -{% for arg in item.args %}* `{{ arg.name }}` ({{ arg.type }}): {{ arg.description }} +{% for arg in item.args %}* `{{ arg.name }}` ({{ arg.type }}): {{ arg.description }}{% if arg.defaultValue != nil %} Default: `{{ arg.defaultValue }}`.{% endif %} {% endfor %} {% endif %} @@ -32,7 +32,7 @@ ### Input fields for `{{ item.name }}` -{% for field in item.inputFields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue %} Default: `{{ field.defaultValue }}`.{% endif %} +{% for field in item.inputFields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue != nil %} Default: `{{ field.defaultValue }}`.{% endif %} {% endfor %} {% endif %} @@ -40,7 +40,7 @@ ### Return fields for `{{ item.name }}` -{% for field in item.returnFields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %} +{% for field in item.returnFields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue != nil %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %} {% endfor %} {% endif %} @@ -54,8 +54,8 @@ ### Fields for `{{ item.name }}` -{% for field in item.fields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %}{% if field.hasPaginationOnly %} _(Pagination: `after`, `before`, `first`, `last`)_{% elsif field.arguments.size > 0 %} -{% for arg in field.arguments %} * `{{ arg.name }}` ({{ arg.type.name }}): {{ arg.description }}{% if arg.defaultValue %} Default: `{{ arg.defaultValue }}`.{% endif %} +{% for field in item.fields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue != nil %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %}{% if field.hasPaginationOnly %} _(Pagination: `after`, `before`, `first`, `last`)_{% elsif field.arguments.size > 0 %} +{% for arg in field.arguments %} * `{{ arg.name }}` ({{ arg.type.name }}): {{ arg.description }}{% if arg.defaultValue != nil %} Default: `{{ arg.defaultValue }}`.{% endif %} {% endfor %}{% endif %} {% endfor %} {% endif %} @@ -65,8 +65,8 @@ ### Fields for `{{ item.name }}` -{% for field in item.fields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %}{% if field.hasPaginationOnly %} _(Pagination: `after`, `before`, `first`, `last`)_{% elsif field.arguments.size > 0 %} -{% for arg in field.arguments %} * `{{ arg.name }}` ({{ arg.type.name }}): {{ arg.description }}{% if arg.defaultValue %} Default: `{{ arg.defaultValue }}`.{% endif %} +{% for field in item.fields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue != nil %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %}{% if field.hasPaginationOnly %} _(Pagination: `after`, `before`, `first`, `last`)_{% elsif field.arguments.size > 0 %} +{% for arg in field.arguments %} * `{{ arg.name }}` ({{ arg.type.name }}): {{ arg.description }}{% if arg.defaultValue != nil %} Default: `{{ arg.defaultValue }}`.{% endif %} {% endfor %}{% endif %} {% endfor %} {% endif %} @@ -102,7 +102,7 @@ ### Input fields for `{{ item.name }}` -{% for field in item.inputFields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %} +{% for field in item.inputFields %}* `{{ field.name }}` ({{ field.type }}): {{ field.description }}{% if field.defaultValue != nil %} Default: `{{ field.defaultValue }}`.{% endif %}{% if field.isDeprecated %} **Deprecated:** {{ field.deprecationReason }}{% endif %} {% endfor %} {% endif %} diff --git a/src/article-api/tests/codeql-cli-transformer-links.test.ts b/src/article-api/tests/codeql-cli-transformer-links.test.ts new file mode 100644 index 000000000000..c77c151f01e6 --- /dev/null +++ b/src/article-api/tests/codeql-cli-transformer-links.test.ts @@ -0,0 +1,32 @@ +import { describe, expect, test, vi } from 'vitest' + +import { CodeQLCliTransformer } from '@/article-api/transformers/codeql-cli-transformer' +import { latest } from '@/versions/lib/enterprise-server-releases' +import type { Context, Page } from '@/types' + +// page.render already rewrote this link to its final /// form. +const ghesHref = `/en/enterprise-server@${latest}/code-security/reference/code-scanning/sarif-files/sarif-support` +const renderedBody = `## Description\n\nSee [SARIF support for GHES](${ghesHref}).` + +const stubPage = { + autogenerated: 'codeql-cli', + title: 'github upload-results', + intro: '', + render: vi.fn().mockResolvedValue(renderedBody), + renderProp: vi.fn().mockResolvedValue(''), +} as unknown as Page + +describe('CodeQLCliTransformer links', () => { + const transformer = new CodeQLCliTransformer() + + test.each(['free-pro-team@latest', 'enterprise-cloud@latest'])( + 'keeps links pinned to Enterprise Server on %s', + async (currentVersion) => { + const context = { currentVersion, currentLanguage: 'en' } as Context + const result = await transformer.transform(stubPage, '', context) + + expect(result).toContain('# github upload-results') + expect(result).toContain(`[SARIF support for GHES](${ghesHref})`) + }, + ) +}) diff --git a/src/article-api/tests/graphql-reference-transformer.test.ts b/src/article-api/tests/graphql-reference-transformer.test.ts new file mode 100644 index 000000000000..ec77151fa850 --- /dev/null +++ b/src/article-api/tests/graphql-reference-transformer.test.ts @@ -0,0 +1,139 @@ +import { describe, expect, test, vi } from 'vitest' + +import { GraphQLReferenceTransformer } from '@/article-api/transformers/graphql-reference-transformer' +import type { Context, Page } from '@/types' + +vi.mock('@/article-api/lib/graphql-helpers', () => ({ + extractManualContent: async () => '', +})) + +vi.mock('@/graphql/lib/index', () => ({ + getAllGraphqlObjects: () => [], + getGraphqlSchema: () => ({ + queries: [ + { + name: 'widget', + id: 'widget', + href: '/graphql/reference/queries#widget', + description: 'Look up a widget.', + type: 'Widget', + args: [ + { + name: 'followRenames', + id: 'followrenames', + href: '/graphql/reference/scalars#boolean', + description: 'Follow renames.', + type: 'Boolean', + defaultValue: true, + }, + { + name: 'dryRun', + id: 'dryrun', + href: '/graphql/reference/scalars#boolean', + description: 'Dry run.', + type: 'Boolean', + defaultValue: false, + }, + { + name: 'owner', + id: 'owner', + href: '/graphql/reference/scalars#string', + description: 'The owner.', + type: 'String!', + }, + ], + }, + ], + objects: [ + { + name: 'Widget', + id: 'widget', + href: '/graphql/reference/objects#widget', + description: 'A widget.', + fields: [ + { + name: 'parts', + id: 'parts', + href: '/graphql/reference/objects#part', + description: 'The parts.', + type: '[Part!]!', + arguments: [ + { + name: 'includeHidden', + description: 'Include hidden parts.', + defaultValue: false, + type: { + name: 'Boolean', + id: 'boolean', + href: '/graphql/reference/scalars#boolean', + }, + }, + { + name: 'includeVisible', + description: 'Include visible parts.', + defaultValue: true, + type: { + name: 'Boolean', + id: 'boolean', + href: '/graphql/reference/scalars#boolean', + }, + }, + { + name: 'label', + description: 'Filter by label.', + type: { name: 'String', id: 'string', href: '/graphql/reference/scalars#string' }, + }, + ], + }, + ], + }, + ], + inputObjects: [ + { + name: 'WidgetInput', + id: 'widgetinput', + href: '/graphql/reference/input-objects#widgetinput', + description: 'Widget input.', + inputFields: [ + { + name: 'archived', + id: 'archived', + href: '/graphql/reference/scalars#boolean', + description: 'Whether the widget is archived.', + type: 'Boolean', + defaultValue: false, + }, + ], + }, + ], + }), +})) + +const stubPage = { + autogenerated: 'graphql', + relativePath: 'graphql/reference/repos.md', + title: 'Widgets', + intro: '', + renderProp: vi.fn().mockResolvedValue(''), +} as unknown as Page + +const context = { currentVersion: 'free-pro-team@latest' } as Context + +describe('GraphQLReferenceTransformer default values', () => { + test('renders true and false defaults and skips missing ones', async () => { + const transformer = new GraphQLReferenceTransformer() + const output = await transformer.transform(stubPage, '/en/graphql/reference/repos', context) + const lines = output.split('\n') + const lineFor = (prefix: string) => lines.find((line) => line.includes(prefix)) ?? '' + + expect(lineFor('`followRenames` (Boolean)')).toContain('Default: `true`.') + expect(lineFor('`dryRun` (Boolean)')).toContain('Default: `false`.') + expect(lineFor('`owner` (String!)')).not.toContain('Default:') + + expect(lineFor('`includeHidden` (Boolean)')).toContain('Default: `false`.') + expect(lineFor('`includeVisible` (Boolean)')).toContain('Default: `true`.') + expect(lineFor('`label` (String)')).not.toContain('Default:') + + expect(lineFor('`archived` (Boolean)')).toContain('Default: `false`.') + }) +}) diff --git a/src/article-api/tests/pagelist-redirect.ts b/src/article-api/tests/pagelist-redirect.ts new file mode 100644 index 000000000000..2ade15b73325 --- /dev/null +++ b/src/article-api/tests/pagelist-redirect.ts @@ -0,0 +1,64 @@ +import { IncomingMessage, ServerResponse } from 'http' +import { Socket } from 'net' + +import express from 'express' +import type { NextFunction, Response } from 'express' +import { describe, expect, test } from 'vitest' + +import type { ExtendedRequest } from '@/types' +import pageList from '@/article-api/middleware/pagelist' +import safeRedirect from '@/frame/middleware/safe-redirect' +import urlDecode from '@/frame/middleware/url-decode' + +// Mirrors the production order where urlDecode rewrites req.url after Express sets req.originalUrl. +function createApp() { + const app = express() + app.use(safeRedirect) + app.use(urlDecode) + app.use((req: ExtendedRequest, res: Response, next: NextFunction) => { + req.context = {} + next() + }) + const api = express.Router() + api.use('/pagelist', pageList) + app.use('/api', api) + return app +} + +function dispatch(url: string): Promise<{ statusCode: number; location: string | undefined }> { + const app = createApp() + return new Promise((resolve) => { + const req = new IncomingMessage(new Socket()) + req.method = 'GET' + req.url = url + const res = new ServerResponse(req) + res.end = function () { + resolve({ + statusCode: res.statusCode, + location: res.getHeader('location') as string | undefined, + }) + return res + } as typeof res.end + app(req, res) + }) +} + +describe('pagelist one-segment redirects', () => { + test('redirects a literal @ version to the English pagelist', async () => { + const res = await dispatch('/api/pagelist/free-pro-team@latest') + expect(res.statusCode).toBe(308) + expect(res.location).toBe('/api/pagelist/en/free-pro-team@latest') + }) + + test('redirects a percent-encoded @ version instead of to itself', async () => { + const res = await dispatch('/api/pagelist/enterprise-cloud%40latest') + expect(res.statusCode).toBe(308) + expect(res.location).toBe('/api/pagelist/en/enterprise-cloud@latest') + }) + + test('keeps the query string when redirecting a percent-encoded @ version', async () => { + const res = await dispatch('/api/pagelist/free-pro-team%40latest?foo=bar') + expect(res.statusCode).toBe(308) + expect(res.location).toBe('/api/pagelist/en/free-pro-team@latest?foo=bar') + }) +}) diff --git a/src/article-api/tests/pagelist.ts b/src/article-api/tests/pagelist.ts index f68c0a9d28dc..633d9e264645 100644 --- a/src/article-api/tests/pagelist.ts +++ b/src/article-api/tests/pagelist.ts @@ -62,6 +62,12 @@ describe('Redirect Tests', () => { expect(res.headers.location).toBe('/api/pagelist/en/free-pro-team@latest') }) + test('redirects a plan name without a version to English', async () => { + const res = await get('/api/pagelist/free-pro-team') + expect(res.statusCode).toBe(308) + expect(res.headers.location).toBe('/api/pagelist/en/free-pro-team@latest') + }) + test('should redirect to /pagelist/en/free-pro-team@lateset when URL does not include version', async () => { const res = await get('/api/pagelist/en') expect(res.statusCode).toBe(308) diff --git a/src/article-api/tests/release-notes-transformer.ts b/src/article-api/tests/release-notes-transformer.ts index 65306f11ed3a..5ffb0adb67ec 100644 --- a/src/article-api/tests/release-notes-transformer.ts +++ b/src/article-api/tests/release-notes-transformer.ts @@ -1,6 +1,7 @@ import { describe, expect, test, vi } from 'vitest' import type { Context, GHESReleasePatch, Page } from '@/types' +import { renderContent } from '@/content-render/index' import { ReleaseNotesTransformer, renderReleaseNotesMarkdown, @@ -170,6 +171,23 @@ describe('renderReleaseNotesMarkdown', () => { expect(out).toContain('### custom_section') }) + test('renders notes in English with AUTOTITLE links in the reader language', async () => { + const mockedRenderContent = vi.mocked(renderContent) + mockedRenderContent.mockClear() + await renderReleaseNotesMarkdown( + 'Title', + '', + [samplePatch()], + makeContext({ currentLanguage: 'ja' }), + ) + + // One patch intro plus six notes in samplePatch. + expect(mockedRenderContent).toHaveBeenCalledTimes(7) + for (const [template, ctx] of mockedRenderContent.mock.calls) { + expect(ctx, template).toMatchObject({ currentLanguage: 'en', autotitleLanguage: 'ja' }) + } + }) + test('skips empty sections', async () => { const patch: GHESReleasePatch = { ...samplePatch(), diff --git a/src/article-api/transformers/codeql-cli-transformer.ts b/src/article-api/transformers/codeql-cli-transformer.ts index 1421cfb4f551..5ff69c840a9a 100644 --- a/src/article-api/transformers/codeql-cli-transformer.ts +++ b/src/article-api/transformers/codeql-cli-transformer.ts @@ -1,6 +1,6 @@ import type { Context, Page } from '@/types' import type { PageTransformer } from './types' -import { renderContent } from '@/content-render/index' +import { renderLiquid } from '@/content-render/liquid/index' import { loadTemplate } from '@/article-api/lib/load-template' import { stripHtmlCommentsAndNormalizeWhitespace } from '@/article-api/lib/strip-html-comments' @@ -28,11 +28,8 @@ export class CodeQLCliTransformer implements PageTransformer { const templateContent = loadTemplate(this.templateName) - const result = await renderContent(templateContent, { - ...context, - ...templateData, - markdownRequested: true, - }) + // page.render already rewrote local links, and a second rewrite pass re-versions pinned links. + const result = await renderLiquid(templateContent, { ...context, ...templateData }) // Strip markdownlint-disable and any other HTML comments. return stripHtmlCommentsAndNormalizeWhitespace(result) diff --git a/src/article-api/transformers/graphql-changelog-transformer.ts b/src/article-api/transformers/graphql-changelog-transformer.ts index e6758add7424..8a2ee915f73a 100644 --- a/src/article-api/transformers/graphql-changelog-transformer.ts +++ b/src/article-api/transformers/graphql-changelog-transformer.ts @@ -39,15 +39,18 @@ export class GraphQLChangelogTransformer implements PageTransformer { const changelogItems = schema.map((item) => { const processChanges = (changes: Array<{ title: string; changes: string[] }>) => - changes.map((change) => ({ - title: change.title, - changes: change.changes.map((html: string) => { - if (html.startsWith('

') && html.endsWith('

')) { - return fastTextOnly(html.slice(3, -4)) - } - return fastTextOnly(html) - }), - })) + changes + // Older changelog data has schema groups with no changes. + .filter((change) => change.changes.length > 0) + .map((change) => ({ + title: change.title, + changes: change.changes.map((html: string) => { + if (html.startsWith('

') && html.endsWith('

')) { + return fastTextOnly(html.slice(3, -4)) + } + return fastTextOnly(html) + }), + })) return { date: item.date, diff --git a/src/article-api/transformers/graphql-reference-transformer.ts b/src/article-api/transformers/graphql-reference-transformer.ts index 5425f179e345..8335f91b0ab5 100644 --- a/src/article-api/transformers/graphql-reference-transformer.ts +++ b/src/article-api/transformers/graphql-reference-transformer.ts @@ -173,6 +173,7 @@ export class GraphQLReferenceTransformer implements PageTransformer { type: arg.type, href: arg.href, description: arg.description ? fastTextOnly(arg.description) : '', + defaultValue: arg.defaultValue, })), } } diff --git a/src/article-api/transformers/release-notes-transformer.ts b/src/article-api/transformers/release-notes-transformer.ts index fca2dc76d612..498cd7624254 100644 --- a/src/article-api/transformers/release-notes-transformer.ts +++ b/src/article-api/transformers/release-notes-transformer.ts @@ -50,8 +50,14 @@ const SECTION_LABELS: Record = { retired: 'Retired', } +// Match ghes-release-notes.ts: reusables render in English, AUTOTITLE links in the reader's language. async function renderNoteMarkdown(raw: string, context: Context): Promise { - return await renderContent(raw, { ...context, markdownRequested: true }) + return await renderContent(raw, { + ...context, + currentLanguage: 'en', + autotitleLanguage: context.currentLanguage, + markdownRequested: true, + }) } // Format text as a list item at the given indent depth. diff --git a/src/assets/middleware/dynamic-assets.ts b/src/assets/middleware/dynamic-assets.ts index b794d2582628..d20748f73625 100644 --- a/src/assets/middleware/dynamic-assets.ts +++ b/src/assets/middleware/dynamic-assets.ts @@ -90,7 +90,7 @@ export default async function dynamicAssets( if ( catchError instanceof Error && 'code' in catchError && - (catchError as NodeJS.ErrnoException).code !== 'ENOENT' + !isFileNotFoundError((catchError as NodeJS.ErrnoException).code) ) { logger.error('Failed to process dynamic asset', { path: req.path, error: catchError }) throw catchError @@ -112,6 +112,12 @@ function sendNotFound(res: Response) { res.status(404).type('text/plain').send('Asset not found') } +// Request paths can run through an existing file or exceed the filename length limit. +// express.static treats these errors as 404s, so match that here. +function isFileNotFoundError(code: string | undefined) { + return code === 'ENOENT' || code === 'ENOTDIR' || code === 'ENAMETOOLONG' +} + function deconstructImageURL(url: string) { let error let maxWidth diff --git a/src/assets/tests/dynamic-assets.ts b/src/assets/tests/dynamic-assets.ts index 4d412f4bd56a..a85aed903511 100644 --- a/src/assets/tests/dynamic-assets.ts +++ b/src/assets/tests/dynamic-assets.ts @@ -100,6 +100,18 @@ describe('dynamic assets', () => { expect(res.headers['content-type']).toMatch(/text\/plain/) }) + test('WebP path through an existing PNG gets a 404', async () => { + const res = await get('/assets/images/_fixtures/screenshot.png/x.webp') + expect(res.statusCode).toBe(404) + expect(res.headers['content-type']).toMatch(/text\/plain/) + }) + + test('WebP filename longer than the filesystem limit gets a 404', async () => { + const res = await get(`/assets/images/${'a'.repeat(300)}.webp`) + expect(res.statusCode).toBe(404) + expect(res.headers['content-type']).toMatch(/text\/plain/) + }) + test.each(['key', 'key=value'])('any query string (%p) triggers a redirect', async (qs) => { const res = await get(`/assets/images/_fixtures/screenshot.webp?${qs}`) expect(res.statusCode).toBe(302) diff --git a/src/automated-pipelines/components/parameter-table/ParameterRow.tsx b/src/automated-pipelines/components/parameter-table/ParameterRow.tsx index 4752b084e908..c2c17f61b760 100644 --- a/src/automated-pipelines/components/parameter-table/ParameterRow.tsx +++ b/src/automated-pipelines/components/parameter-table/ParameterRow.tsx @@ -4,6 +4,7 @@ import { useTranslation } from '@/languages/components/useTranslation' import { ChildBodyParametersRows } from './ChildBodyParametersRows' import type { ChildParameter } from './types' import { RenderedHTML } from '@/frame/components/ui/RenderedHTML/RenderedHTML' +import { NO_CHILD_WEBHOOK_PROPERTIES } from '@/webhooks/lib/no-child-properties' type Props = { rowParams: ChildParameter @@ -15,18 +16,6 @@ type Props = { clickedBodyParameterName?: string | undefined } -// The webhooks page documents common webhook payload properties in one shared section. -// Skipping their child properties here avoids duplicate schema lookups and repeated docs. -// https://docs.github.com/en/webhooks/webhook-events-and-payloads -const NO_CHILD_WEBHOOK_PROPERTIES = [ - 'action', - 'enterprise', - 'installation', - 'organization', - 'repository', - 'sender', -] - export function ParameterRow({ rowParams, slug, @@ -99,7 +88,16 @@ export function ParameterRow({ {rowParams.enum.map((item, index, array) => ( - {item === null ? null : item} + + {item === null ? ( + null + ) : typeof item === 'string' ? ( + item + ) : ( + // React renders nothing for boolean children. + JSON.stringify(item) + )} + {index !== array.length - 1 && ','}{' '} ))} @@ -127,9 +125,10 @@ export function ParameterRow({ /> )} - {/* Empty child groups mark unloaded nested params except shared webhook props; details lazy-loads them. */} - {rowParams.type && - (rowParams.type.includes('object') || rowParams.type.includes('array of')) && + {/* Empty child groups mark unloaded webhook objects except shared props; only rows with a callback can load them. */} + {bodyParamExpandCallback && + rowParams.type && + rowParams.type.includes('object') && rowParams.childParamsGroups && rowParams.childParamsGroups.length === 0 && !NO_CHILD_WEBHOOK_PROPERTIES.includes(rowParams.name) ? ( @@ -139,10 +138,7 @@ export function ParameterRow({ data-nested-param-id={rowParams.name} className="box px-3 ml-1 mb-0" onToggle={(event) => { - if (bodyParamExpandCallback) { - const target = event.target as HTMLDetailsElement - bodyParamExpandCallback(target) - } + bodyParamExpandCallback(event.target as HTMLDetailsElement) }} >