diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..5f01957 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,9 @@ +FROM mcr.microsoft.com/devcontainers/python:3.11-bookworm + +ARG NPM_CONFIG_REGISTRY +ARG PIP_INDEX_URL +ARG RestoreSources + +ENV NPM_CONFIG_REGISTRY="${NPM_CONFIG_REGISTRY:-https://registry.npmjs.org/}" \ + PIP_INDEX_URL="${PIP_INDEX_URL:-https://pypi.org/simple/}" \ + RestoreSources="${RestoreSources:-https://api.nuget.org/v3/index.json}" diff --git a/.devcontainer/Dockerfile.opt b/.devcontainer/Dockerfile.opt deleted file mode 100644 index 1fb62c7..0000000 --- a/.devcontainer/Dockerfile.opt +++ /dev/null @@ -1,52 +0,0 @@ -FROM mcr.microsoft.com/devcontainers/python:3.11-bookworm - -# --- Root-level installs --- - -# # Docker CLI + Compose plugin (https://docs.docker.com/engine/install/debian/) -# RUN install -m 0755 -d /etc/apt/keyrings \ -# && curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \ -# && chmod a+r /etc/apt/keyrings/docker.asc \ -# && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" \ -# > /etc/apt/sources.list.d/docker.list \ -# && apt-get update \ -# && apt-get install -y --no-install-recommends docker-ce-cli docker-compose-plugin \ -# && apt-get clean && rm -rf /var/lib/apt/lists/* - -# GitHub CLI (https://github.com/cli/cli/blob/trunk/docs/install_linux.md) -RUN mkdir -p -m 755 /etc/apt/keyrings \ - && wget -nv -O- https://cli.github.com/packages/githubcli-archive-keyring.gpg \ - | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ - && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ - && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ - > /etc/apt/sources.list.d/github-cli.list \ - && apt-get update \ - && apt-get install -y gh \ - && apt-get clean && rm -rf /var/lib/apt/lists/* - -# # Azure CLI (https://learn.microsoft.com/cli/azure/install-azure-cli-linux?pivots=apt) -# RUN curl -sL https://aka.ms/InstallAzureCLIDeb | bash - -# just (https://just.systems/man/en/pre-built-binaries.html) -RUN curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin - -# Add vscode user to docker group -RUN groupadd -f docker && usermod -aG docker vscode - -# Shell history directory -RUN mkdir -p /commandhistory && chown vscode:vscode /commandhistory - -# --- User-level installs --- -USER vscode - -# Node.js LTS via nvm (already in base image) -RUN bash -c "source /usr/local/share/nvm/nvm.sh && nvm install --lts" - -# uv (https://docs.astral.sh/uv/getting-started/installation/) -RUN curl -LsSf https://astral.sh/uv/install.sh | sh - -# install copilot cli -RUN curl -fsSL https://gh.io/copilot-install | bash - -# Shell history config -RUN echo 'export HISTFILE=/commandhistory/.zsh_history' >> ~/.zshrc \ - && echo 'export HISTFILE=/commandhistory/.bash_history' >> ~/.bashrc diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json new file mode 100644 index 0000000..0ddb658 --- /dev/null +++ b/.devcontainer/devcontainer-lock.json @@ -0,0 +1,59 @@ +{ + "features": { + "ghcr.io/devcontainers/features/azure-cli:1": { + "version": "1.3.0", + "resolved": "ghcr.io/devcontainers/features/azure-cli@sha256:d98f1066c077be0fa9d115b718f458bd803e415181b4a96f82a6f5d9f77241ac", + "integrity": "sha256:d98f1066c077be0fa9d115b718f458bd803e415181b4a96f82a6f5d9f77241ac" + }, + "ghcr.io/devcontainers/features/common-utils:2": { + "version": "2.5.9", + "resolved": "ghcr.io/devcontainers/features/common-utils@sha256:cb0c4d3c276f157eed17935747e364178d75fee17f55c4e129966f64633deb3a", + "integrity": "sha256:cb0c4d3c276f157eed17935747e364178d75fee17f55c4e129966f64633deb3a" + }, + "ghcr.io/devcontainers/features/copilot-cli": { + "version": "1.1.3", + "resolved": "ghcr.io/devcontainers/features/copilot-cli@sha256:e10d091ae7ef9b8d2ed5f601d75f5a090bc04acbac1a26d4cd3c0d5edde4ea10", + "integrity": "sha256:e10d091ae7ef9b8d2ed5f601d75f5a090bc04acbac1a26d4cd3c0d5edde4ea10" + }, + "ghcr.io/devcontainers/features/docker-outside-of-docker": { + "version": "1.10.0", + "resolved": "ghcr.io/devcontainers/features/docker-outside-of-docker@sha256:c2c2cf829505ead8e4892c88c31b6594ae94a2bbb209e16e1fac456c1a3a624e", + "integrity": "sha256:c2c2cf829505ead8e4892c88c31b6594ae94a2bbb209e16e1fac456c1a3a624e" + }, + "ghcr.io/devcontainers/features/github-cli": { + "version": "1.1.0", + "resolved": "ghcr.io/devcontainers/features/github-cli@sha256:d22f50b70ed75339b4eed1ba9ecde3a1791f90e88d37936517e3bace0bbad671", + "integrity": "sha256:d22f50b70ed75339b4eed1ba9ecde3a1791f90e88d37936517e3bace0bbad671" + }, + "ghcr.io/devcontainers/features/node:2.1.0": { + "version": "2.1.0", + "resolved": "ghcr.io/devcontainers/features/node@sha256:586c9a6f7dd40bd3ba2cd41e7f2f88dcc31fbe5d1442afcbf07ffbc66b686857", + "integrity": "sha256:586c9a6f7dd40bd3ba2cd41e7f2f88dcc31fbe5d1442afcbf07ffbc66b686857" + }, + "ghcr.io/jsburckhardt/devcontainer-features/glow": { + "version": "1.0.0", + "resolved": "ghcr.io/jsburckhardt/devcontainer-features/glow@sha256:62ff23e23b936c28ad32300151a33cacaa552d10a29b8991a33797d42d0e0ec0", + "integrity": "sha256:62ff23e23b936c28ad32300151a33cacaa552d10a29b8991a33797d42d0e0ec0" + }, + "ghcr.io/jsburckhardt/devcontainer-features/tmux": { + "version": "2.0.0", + "resolved": "ghcr.io/jsburckhardt/devcontainer-features/tmux@sha256:65d1809a7e1b03b3a5d272443b5ab1832ed795439aec0ed3c655c73856bc6c8a", + "integrity": "sha256:65d1809a7e1b03b3a5d272443b5ab1832ed795439aec0ed3c655c73856bc6c8a" + }, + "ghcr.io/jsburckhardt/devcontainer-features/uv:1": { + "version": "1.0.0", + "resolved": "ghcr.io/jsburckhardt/devcontainer-features/uv@sha256:542a0bc2203205b3c696de650ba862f280b20af3543493cc232edd9ac35791f7", + "integrity": "sha256:542a0bc2203205b3c696de650ba862f280b20af3543493cc232edd9ac35791f7" + }, + "ghcr.io/rosstaco/devcontainer-features/copilot-persistence": { + "version": "1.1.0", + "resolved": "ghcr.io/rosstaco/devcontainer-features/copilot-persistence@sha256:6dd5cd9b007544b542d8aa71c09e5076ac0b81cae293ba59a8fb78c26119a610", + "integrity": "sha256:6dd5cd9b007544b542d8aa71c09e5076ac0b81cae293ba59a8fb78c26119a610" + }, + "ghcr.io/stuartleeks/dev-container-features/shell-history": { + "version": "0.0.6", + "resolved": "ghcr.io/stuartleeks/dev-container-features/shell-history@sha256:f266af2d093e0611921ccf510046e53affeccb353405ee05d2b91fcc4f69c1c9", + "integrity": "sha256:f266af2d093e0611921ccf510046e53affeccb353405ee05d2b91fcc4f69c1c9" + } + } +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5d6c1ed..8b8606e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,13 @@ { "name": "copilot-cli-deep-dive-workshop", - "image": "mcr.microsoft.com/devcontainers/python:3.11-bookworm", + "build": { + "dockerfile": "Dockerfile", + "args": { + "NPM_CONFIG_REGISTRY": "${localEnv:NPM_CONFIG_REGISTRY}", + "PIP_INDEX_URL": "${localEnv:PIP_INDEX_URL}", + "RestoreSources": "${localEnv:RestoreSources}" + } + }, "runArgs": [ "--name", "ccddw" @@ -12,7 +19,7 @@ "installOhMyZshConfig": true }, "ghcr.io/devcontainers/features/docker-outside-of-docker": {}, - "ghcr.io/devcontainers/features/node": { + "ghcr.io/devcontainers/features/node:2.1.0": { "version": "lts" }, "ghcr.io/devcontainers/features/azure-cli:1": {}, @@ -22,7 +29,10 @@ }, "ghcr.io/stuartleeks/dev-container-features/shell-history": {}, "ghcr.io/devcontainers/features/github-cli": {}, - "ghcr.io/devcontainers/features/copilot-cli": {} + "ghcr.io/devcontainers/features/copilot-cli": {}, + "ghcr.io/rosstaco/devcontainer-features/copilot-persistence": {}, + "ghcr.io/jsburckhardt/devcontainer-features/tmux": {}, + "ghcr.io/jsburckhardt/devcontainer-features/glow": {} }, "customizations": { "vscode": { diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6669b07..5cfc781 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -31,7 +31,7 @@ WORKSHOP_FLOW: "Installation (01) -> Core Concepts (02-05) -> Advanced (06-13)" WORKSHOP_DURATION: "~4.5 hours" MODULE_COUNT: 13 SLIDE_SYNC_RULE: "When modifying docs/workshop/NN-*.md, always check and update docs/slides/NN-*.md" -VALIDATED_CLI_VERSION: "1.0.69-1" +VALIDATED_CLI_VERSION: "1.0.79-5" DOCKER_SETUP: TEXT docker run -it --name copilot-workshop \ diff --git a/README.md b/README.md index ac86f0d..a63aadc 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # GitHub Copilot CLI โ€” Deep-Dive Workshop -[![Copilot CLI version](https://img.shields.io/badge/Copilot%20CLI-v1.0.69--1-blue?logo=github)](https://github.com/github/copilot-cli/releases/tag/v1.0.69-1) +[![Copilot CLI version](https://img.shields.io/badge/Copilot%20CLI-v1.0.79--5-blue?logo=github)](https://github.com/github/copilot-cli/releases/tag/v1.0.79-5) [![APS version](https://img.shields.io/badge/APS-v1.2.1-blue?logo=github)](https://github.com/chris-buckley/agnostic-prompt-standard/releases/tag/v1.2.1) -A **half-day, instructor-led** workshop that takes teams from first install to advanced automation with GitHub Copilot CLI. Covers operating modes, custom instructions, MCP servers, agent skills, plugins, custom agents, hooks, context management, and more โ€” all through hands-on exercises validated against **Copilot CLI v1.0.69-1**. +A **half-day, instructor-led** workshop that takes teams from first install to advanced automation with GitHub Copilot CLI. Covers operating modes, custom instructions, MCP servers, agent skills, plugins, custom agents, hooks, context management, and more โ€” all through hands-on exercises validated against **Copilot CLI v1.0.79-5**. ## What's Inside @@ -46,6 +46,12 @@ This repo includes a `.devcontainer` configuration for a fully isolated workshop 2. Click **"Reopen in Container"** when prompted (or run `Dev Containers: Reopen in Container` from the command palette) 3. All prerequisites (Node.js, npm, git, gh) are pre-installed +The Dev Container passes `NPM_CONFIG_REGISTRY`, `PIP_INDEX_URL`, and `RestoreSources` +from the environment that launches VS Code into the image build and the resulting +container. Export these variables before starting VS Code, then rebuild the container +after changing them. If a variable is not set, the Dev Container uses the corresponding +public npm, PyPI, or NuGet registry. + > This is the recommended approach โ€” it avoids polluting your host machine and ensures a consistent environment for all participants. ### Alternative: Run Directly on Host diff --git a/docs/index.html b/docs/index.html index f01d0ca..9e9a594 100644 --- a/docs/index.html +++ b/docs/index.html @@ -33,7 +33,7 @@

GitHub Copilot CLI
Deep-Dive Workshop

Modules
-
v1.0.69-1
+
v1.0.79-5
Copilot CLI
@@ -57,12 +57,12 @@

Custom Instructions

๐Ÿ”Œ

MCP Servers & Tools

-

Connect to GitHub MCP, configure local/remote servers, and manage tool permissions effectively.

+

Connect to GitHub MCP, configure local/remote servers, and control access with permission modes and command sandboxing.

๐Ÿค–

Agents & Skills

-

Build custom agents, create reusable skills, and leverage the plugin ecosystem.

+

Build custom agents, create reusable skills alongside the built-in ones, and leverage the plugin ecosystem.

๐Ÿช
@@ -72,7 +72,7 @@

Hooks & Automation

โš™๏ธ

Configuration

-

Context management, session handling, IDE integration, accessibility, and team standardization.

+

User settings, session limits and AI credits, context management, IDE integration, accessibility, and team standardization.

diff --git a/docs/slides/01-installation.md b/docs/slides/01-installation.md index 1349671..374f9a9 100644 --- a/docs/slides/01-installation.md +++ b/docs/slides/01-installation.md @@ -74,7 +74,7 @@ style: | |--------|---------|----------| | **Script** | `curl -fsSL https://gh.io/copilot-install \| bash` | Quick setup | | npm | `npm install -g @github/copilot` | Node.js devs | -| Homebrew | `brew install copilot-cli` | macOS/Linux | +| Homebrew | `brew install --cask copilot-cli` | macOS | | WinGet | `winget install GitHub.Copilot` | Windows | | Dev Container | Built-in | Codespaces | @@ -85,15 +85,56 @@ style: | ## Authentication ```bash -# Start Copilot โ€” browser opens for OAuth +# Start Copilot โ€” OAuth flow begins copilot +# Force a specific OAuth mode +copilot login --web-flow # browser (default on desktops) +copilot login --device-code # default when remote/headless + # Or use a token (CI/CD, containers) export COPILOT_GITHUB_TOKEN="github_pat_your_token" copilot ``` -For containers/CI: create a **fine-grained PAT** with **"Copilot Requests"** permission +For containers/CI: create a **fine-grained PAT** with **"Copilot Requests"** permission โ€” classic PATs (`ghp_`) are **not** supported + +--- + +## Enterprise Cloud & Signing Out + +**GHEC data residency** โ€” authenticate against your enterprise host: + +```bash +copilot login --host https://example.ghe.com +``` + +Credentials are stored separately from github.com, so you connect to your +enterprise's dedicated environment. + +**Signing out:** when you signed in via the **gh CLI, a PAT, an API key, or an +env var**, `/logout` displays a warning โ€” that credential source must be +removed separately. + +--- + +## Shell Completion + +Tab completion for `copilot` subcommands and flags: + +```bash +# Bash (current session) +source <(copilot completion bash) + +# Bash (persistent, Linux) +copilot completion bash | sudo tee /etc/bash_completion.d/copilot + +# Zsh โ€” write to a directory on your $fpath, then restart the shell +copilot completion zsh > "${fpath[1]}/_copilot" + +# Fish +copilot completion fish > ~/.config/fish/completions/copilot.fish +``` --- @@ -127,6 +168,10 @@ copilot --version # Check for updates copilot version +# Update on a specific channel +copilot update stable +copilot update prerelease + # Inside a session: /version ``` diff --git a/docs/slides/02-modes.md b/docs/slides/02-modes.md index 5f0bc7c..45e52a1 100644 --- a/docs/slides/02-modes.md +++ b/docs/slides/02-modes.md @@ -116,6 +116,23 @@ Perfect for: automation, CI/CD, scripting --- +## Programmatic Mode: Machine-Readable Output + +```bash +# JSON output for scripting +copilot -p "list all TODO comments" --output-format json +``` + +```bash +# Silent mode โ€” agent response only, no stats +copilot -p "What is 2+2?" -s +``` + +Pair `--output-format json` with a parser like `jq`; use `-s` when you want +the response text alone, with no session statistics around it. + +--- + ## Delegate Mode **Hand off to a cloud agent** โ€” it creates a branch and PR @@ -138,18 +155,22 @@ Type **`/help`** to see them all | Category | Key commands | |----------|-------------| -| **Review** | `/plan`, `/review`, `/rubber-duck`, `/security-review`, `/diff`, `/research`, `/undo` | -| **Session** | `/clear`, `/resume`, `/rename`, `/session`, `/usage` | +| **Review** | `/plan`, `/review`, `/rubber-duck`, `/security-review`, `/diff`, `/research`, `/rewind` | +| **Session** | `/clear`, `/resume`, `/rename`, `/fork`, `/session`, `/usage` | | **Navigation** | `/cwd`, `/add-dir`, `/list-dirs` | | **Context** | `/context`, `/compact` | -| **Config** | `/model`, `/mcp`, `/plugin`, `/settings`, `/subagents`, `/instructions` | -| **Tools** | `/allow-all`, `/reset-allowed-tools` | +| **Config** | `/model`, `/mcp`, `/plugin`, `/theme`, `/settings`, `/statusline`, `/subagents`, `/instructions` | +| **Tools** | `/permissions`, `/allow-all`, `/reset-allowed-tools` | | **Extensibility** | `/skills`, `/plugin`, `/agent`, `/fleet` | | **Scheduling** | `/after`, `/every` | | **Sharing** | `/share`, `/feedback`, `/copy` | | **Account** | `/login`, `/logout`, `/user` | | **IDE** | `/ide` | -| **System** | `/help`, `/exit`, `/init`, `/tasks`, `/lsp`, `/update`, `/restart`, `/version`, `/chronicle`, `/limits` | +| **System** | `/help`, `/changelog`, `/exit`, `/init`, `/tasks`, `/lsp`, `/update`, `/restart`, `/version`, `/chronicle`, `/limits` | + +> Most commands have aliases โ€” `/yolo` โ†’ `/allow-all`, `/cd` โ†’ `/cwd`, `/undo` โ†’ `/rewind` +> `/theme` with no argument opens the theme picker; `/settings theme dim` sets it directly +> (themes: `default`, `github`, `dim`, `high-contrast`, `colorblind`) --- @@ -162,7 +183,7 @@ Type **`/help`** to see them all | `!` | Run shell commands directly (only way to access shell) | | `Shift+Tab` | Cycle between chat โ†’ plan โ†’ autopilot mode | | `Esc` | Cancel current operation | -| `Double-Esc` | Clear input or trigger undo | +| `Double-Esc` | Clear input, or rewind the last turn | | `ctrl+t` | Toggle reasoning display | | `ctrl+x โ†’ /` | Quick slash command | | `ctrl+c` | Cancel / clear input / exit | @@ -243,6 +264,33 @@ When Copilot wants to run a command, you choose: --- +## Permission Modes & Session Limits + +Switch how much the agent may do on its own: + +``` +/permissions manual # approve every request +/permissions assisted # auto-approve what a safety check deems safe +/permissions allow-all # auto-approve tools, paths, and URLs +/permissions show # show current status +``` + +Cap what a session may spend (opt-in, minimum **30** AI credits): + +```bash +copilot --max-ai-credits 30 +``` + +``` +/limits # interactive limits dialog +/limits set max-ai-credits 50 +/limits unset all +``` + +> The AI credit limit is a **soft cap** โ€” usage is known only after a response returns + +--- + ## Your Turn! ๐Ÿš€ Open **Module 2** in `docs/workshop/02-modes.md` diff --git a/docs/slides/03-instructions.md b/docs/slides/03-instructions.md index 3841846..b830b67 100644 --- a/docs/slides/03-instructions.md +++ b/docs/slides/03-instructions.md @@ -71,11 +71,12 @@ With instructions, Copilot **knows**: --- -## Three Files That Shape Behavior +## Files That Shape Behavior | File | Scope | Think of it as... | |------|-------|-------------------| | `AGENTS.md` | Directory tree | **"Who you are"** | +| `CLAUDE.md` / `GEMINI.md` | Git root + cwd | **"Who you are"** (cross-tool) | | `.github/copilot-instructions.md` | Whole repo | **"How we code here"** | | `.github/instructions/*.instructions.md` | File patterns | **"Special rules for these files"** | @@ -88,10 +89,13 @@ Highest wins โ†“ ``` 1. Your prompt โ† always wins 2. AGENTS.md (nearest in directory tree) + + CLAUDE.md / GEMINI.md (git root & cwd) 3. .github/copilot-instructions.md -4. .github/instructions/*.instructions.md -5. ~/.copilot/instructions.md (personal) -6. Default behavior โ† fallback +4. .github/instructions/**/*.instructions.md +5. ~/.copilot/copilot-instructions.md (personal) +6. ~/.copilot/instructions/**/*.instructions.md +7. COPILOT_CUSTOM_INSTRUCTIONS_DIRS +8. Default behavior โ† fallback ``` > They **stack** โ€” all active instructions are combined @@ -156,6 +160,48 @@ Saved as `.github/instructions/tests.instructions.md` --- +## `applyTo` Accepts Two Forms + +```yaml +# Comma-separated string +applyTo: "**/*.ts,**/*.tsx" +``` + +```yaml +# YAML array +applyTo: + - "**/*.ts" + - "**/*.tsx" +``` + +- Files with `applyTo` are **consolidated into a single table** in `/instructions` + output โ€” grouping them reduces context usage +- Instruction files discovered from **multiple paths are deduplicated** โ€” each + unique file is loaded only once + +--- + +## Controlling What Gets Loaded + +Start without any custom instructions at all: + +```bash +copilot --no-custom-instructions +``` + +Add extra directories for instruction discovery, beyond the git root and cwd: + +```bash +export COPILOT_CUSTOM_INSTRUCTIONS_DIRS="/path/to/shared-instructions,/path/to/team-standards" +copilot +``` + +Comma-separated list of directories โ€” useful for shared team standards kept +outside the repository. Files found there sit at the bottom of the priority +stack, and overlap with the project directory is deduplicated. + +--- + ## Practical Tips - **Be specific** โ€” โŒ "Be helpful" โ†’ โœ… "You are a senior React developer" diff --git a/docs/slides/04-tools.md b/docs/slides/04-tools.md index 8df91eb..d9dcb33 100644 --- a/docs/slides/04-tools.md +++ b/docs/slides/04-tools.md @@ -63,17 +63,37 @@ style: | | Tool | Purpose | Risk | |------|---------|------| -| `shell` | Execute shell commands | โš ๏ธ High | -| `write` | Create/modify files | โš ๏ธ High | -| `read` | Read file contents | Low | -| `show_file` | Present code/diffs to user | Low | -| `web_fetch` | Fetch web content | Medium | -| `mcp` | Use MCP server tools | Varies | +| `bash` | Execute shell commands | โš ๏ธ High | +| `create` / `edit` | Create and modify files | โš ๏ธ High | +| `view` | Read files, list directories | Low | +| `glob` / `grep` | Find files, search contents | Low | +| `web_fetch` / `web_search` | Fetch and search the web | Medium | +| `task` / `skill` | Delegate to subagents, load skills | Varies | +| MCP server tools | Contributed by configured servers | Varies | Every destructive action **requires your approval** --- +## Tools โ‰  Permission Kinds + +Permission rules match **kinds**, not tool names: + +| Kind | Matches | +|------|---------| +| `shell(command)` | Shell commands run by the `bash` tool | +| `write(path)` | File creation and modification | +| `(tool-name)` | Tools from an MCP server | +| `url(domain-or-url)` | URL access | + +```bash +copilot --allow-tool 'shell(git:*)' --deny-tool 'shell(git push)' +``` + +> Filter by *tool name* with `--available-tools` / `--excluded-tools` + +--- + ## Approval Workflow Three choices when Copilot wants to use a tool: @@ -90,6 +110,25 @@ Three choices when Copilot wants to use a tool: --- +## Permission Modes + +`/permissions` switches the whole session at once: + +| Mode | Behavior | +|------|----------| +| `manual` | Approve every request | +| `assisted` | Auto-approve what a safety check deems safe | +| `allow-all` | Auto-approve tools, paths, and URLs | +| `show` | Report the current mode | + +``` +/permissions +/permissions allow-all +/permissions show +``` + +--- + ## --allow-tool & --deny-tool Pre-approve or block tools for **programmatic mode** @@ -149,6 +188,44 @@ copilot --no-ask-user --allow-all --- +## Command Sandboxing ๐Ÿงช + +A **third layer** on top of tool and path permissions + +``` +/sandbox # status / policy dialog +/sandbox enable +/sandbox disable +``` + +Shell commands run inside an OS-level sandbox โ€” restricted **filesystem**, **network**, and **credentials** + +- Experimental: needs `--experimental` or `/settings experimental on` +- Backends: Seatbelt (macOS), bubblewrap (Linux), ProcessContainer (Windows) +- Configured under `sandbox.*` in `~/.copilot/settings.json` + +> `copilot help sandbox` has the full reference + +--- + +## โš ๏ธ Never Print `config.json` + +```bash +# DON'T: this prints your live auth token +cat ~/.copilot/config.json + +# DO: read only the key you need +grep -v '^[[:space:]]*//' ~/.copilot/config.json \ + | jq -r '.trustedFolders[]?' +``` + +- `~/.copilot/config.json` โ€” **managed automatically**, holds credentials and `trustedFolders` +- `~/.copilot/settings.json` โ€” **your settings**; edit with `/settings` + +Especially important while screen-sharing + +--- + ## Your Turn! ๐Ÿš€ Open **Module 4** in `docs/workshop/04-tools.md` @@ -160,7 +237,7 @@ Open **Module 4** in `docs/workshop/04-tools.md` - **Exercise 3** โ€” `--allow-tool` flag - **Exercise 4** โ€” `--deny-tool` flag - **Exercise 5** โ€” YOLO mode -- **Exercise 6** โ€” Trusted directories +- **Exercise 6** โ€” Trusted directories (+ safe config inspection) - **Exercise 7** โ€” Safe automation script โฑ๏ธ You have **~16 minutes** diff --git a/docs/slides/05-mcps.md b/docs/slides/05-mcps.md index e4a20ec..010914f 100644 --- a/docs/slides/05-mcps.md +++ b/docs/slides/05-mcps.md @@ -163,6 +163,23 @@ Use shell commands or the interactive `/mcp` view: --- +## `/mcp` Subcommands + +The interactive view also takes subcommands: + +| Command | Action | +|---------|--------| +| `/mcp list` | List attached servers and status | +| `/mcp show ` | Server details and available tools | +| `/mcp add` / `/mcp edit ` | Interactive add/edit wizard | +| `/mcp enable` / `/mcp disable ` | Toggle a server (persists) | +| `/mcp delete ` | Delete a server | +| `/mcp reload` | Reload config and restart servers | +| `/mcp auth ` | Authenticate with a remote server | +| `/mcp search [query]` | Search the MCP registry | + +--- + ## GitHub MCP Server Controls ```bash diff --git a/docs/slides/06-skills.md b/docs/slides/06-skills.md index 8f5b46e..3695e0c 100644 --- a/docs/slides/06-skills.md +++ b/docs/slides/06-skills.md @@ -107,6 +107,28 @@ description: Generates API documentation from source code # Markdown body with detailed instructions... ``` +Optional frontmatter: `license`, `user-invocable`, `aliases`, +`allowed-tools`, `disable-model-invocation` + +--- + +## Built-in Skills + +Two skills ship with the CLI and need **no configuration**: + +| Skill | What it does | +|-------|--------------| +| `customize-cloud-agent` | Configure the Copilot cloud agent environment โ€” `copilot-setup-steps.yml`, preinstalled tools, runners, settings | +| `github-pr-media` | Upload images/video to GitHub's user attachments API and embed them in a PR description or comment | + +```bash +copilot skill list # built-ins listed alongside your skills +``` + +> Built-ins can't be deleted, but they can be disabled +> (`copilot plugins disable --skill`) or overridden by a +> project/personal skill with the same name + --- ## Skill Locations @@ -126,6 +148,7 @@ description: Generates API documentation from source code copilot skill add --project ./my-skill/SKILL.md copilot skill add https://example.com/my-skill/SKILL.md copilot skill list --json +copilot skill remove my-skill ``` --- @@ -139,8 +162,8 @@ Open **Module 6** in `docs/workshop/06-skills.md` - **Exercise 1** โ€” Create a project skill - **Exercise 2** โ€” Skill with resource files - **Exercise 3** โ€” Personal skills -- **Exercise 4** โ€” Discover skills from agentskills.io +- **Exercise 4** โ€” Discover and install community skills - **Exercise 5** โ€” Skill with scripts -- **Exercise 6** โ€” Skill invocation +- **Exercise 6** โ€” Understanding skill auto-selection โฑ๏ธ You have **~16 minutes** diff --git a/docs/slides/07-plugins.md b/docs/slides/07-plugins.md index 4b5ca94..cb94547 100644 --- a/docs/slides/07-plugins.md +++ b/docs/slides/07-plugins.md @@ -65,7 +65,7 @@ style: | โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Copilot CLI โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค -โ”‚ Built-in Tools โ”‚ shell, read, write +โ”‚ Built-in Tools โ”‚ bash, view, create, edit โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ MCP Servers โ”‚ Module 5 โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค @@ -83,8 +83,9 @@ Plugins = **packaged integrations** from the ecosystem | Source | What you'll find | |--------|-----------------| -| **github/copilot-plugins** | Official GitHub plugins | -| **github/awesome-copilot** | Community plugins | +| **github/copilot-plugins** | Official GitHub plugins (default marketplace) | +| **github/awesome-copilot** | Community-curated plugins (default marketplace) | +| **microsoft/work-iq-mcp** | Enterprise integrations | | **GitHub repos** | Direct `owner/repo` installs | | **Repo subdirectories** | `owner/repo:path` plugin layouts | | **Git URLs** | Direct git install sources | @@ -126,15 +127,39 @@ copilot plugin install https://github.com/owner/my-plugin.git ```bash copilot plugin list -copilot plugin update +copilot plugin update spark@copilot-plugins +copilot plugin update --all copilot plugin uninstall workiq copilot plugin marketplace update ``` +> `copilot plugin update` needs a plugin name **or** `--all` > Use `--plugin-dir /path/to/plugin` for local plugin development --- +## `copilot plugins` (plural) + +One command for **plugins, MCP servers, skills, instructions, LSPs** + +```bash +copilot plugins list +copilot plugins list --kind mcp --kind skill +copilot plugins list --scope user --json + +copilot plugins install --skill --scope project ./my-skill/SKILL.md +copilot plugins enable github --mcp +copilot plugins disable my-skill --skill +copilot plugins remove spark@copilot-plugins +``` + +Kinds: `plugin`, `mcp`, `skill`, `instruction`, `lsp` +Scopes: `user`, `repository`, `organization`, `plugin`, `builtin`, `unknown` + +> `/plugins` opens the same view as an interactive dashboard + +--- + ## Security Checklist Before installing any plugin: @@ -161,9 +186,12 @@ copilot --allow-tool 'plugin-name' --deny-tool 'shell(rm)' - **LSP servers** โ€” code intelligence - **Marketplace catalogs** โ€” discoverable plugin listings +Hook and plugin scripts receive `PLUGIN_ROOT`, `PLUGIN_DATA`, and +`COPILOT_PROJECT_DIR` (plus `COPILOT_`/`CLAUDE_` variants) + --- -## Your Turn! +## Your Turn! ๐Ÿš€ Open **Module 7** in `docs/workshop/07-plugins.md` @@ -171,10 +199,11 @@ Open **Module 7** in `docs/workshop/07-plugins.md` - **Exercise 1** โ€” Explore official plugins - **Exercise 2** โ€” Explore work-iq-mcp -- **Exercise 3** โ€” Install a community plugin +- **Exercise 3** โ€” Install a community MCP server - **Exercise 4** โ€” Database plugin integration - **Exercise 5** โ€” Create a custom plugin - **Exercise 6** โ€” Plugin security review - **Exercise 7** โ€” Plugin discovery +- **Exercise 8** โ€” Inspect everything with `copilot plugins` -Timebox: **~12 minutes** +โฑ๏ธ You have **~12 minutes** diff --git a/docs/slides/08-custom-agents.md b/docs/slides/08-custom-agents.md index b82318d..1b4d421 100644 --- a/docs/slides/08-custom-agents.md +++ b/docs/slides/08-custom-agents.md @@ -68,7 +68,7 @@ style: | - ๐Ÿšซ Clear boundaries - ๐Ÿ“š Domain knowledge -Live in **`.github/agents/name.agent.md`** or **`~/.config/copilot/agents/`** +Live in **`.github/agents/name.agent.md`**, **`.claude/agents/`**, or **`~/.copilot/agents/`** Create with **`/agent`** slash command or manually @@ -85,6 +85,8 @@ tools: # optional (default = all) - shell - read - write +skills: # optional: eagerly load named skills + - test-writer --- # Test Writing Agent @@ -100,6 +102,37 @@ File: `.github/agents/test-agent.agent.md` --- +## The `skills:` Field + +Without `skills:`, skills load **on-demand** based on prompt matching. + +```yaml +skills: + - api-docs + - test-writer +``` + +`skills:` declares which skills are **eagerly loaded** when the agent is +invoked โ€” the agent always has that skill content available. + +> The `model` field accepts display names and vendor suffixes in addition to +> full model identifiers. Copilot resolves the closest matching model. + +--- + +## โš ๏ธ Restart to Load New Agents + +| How the agent got there | Availability | +|-------------------------|--------------| +| Manually created `.agent.md` file | **Requires a CLI restart** | +| Edited an existing `.agent.md` file | **Requires a CLI restart** | +| Installed via `/plugin install` | **Hot-loaded** โ€” available immediately | + +If a new agent doesn't show up in `/agent`, it almost certainly means +the CLI hasn't been restarted yet โ€” not that the file is wrong. + +--- + ## Invoking Custom Agents | Method | Example | @@ -113,30 +146,33 @@ File: `.github/agents/test-agent.agent.md` ## Built-in Agents -Invoked automatically โ€” not listed in `/agent` menu +Not listed in the `/agent` menu -| Agent | What it does | Trigger | +| Agent | What it does | How it runs | |-------|-------------|---------| -| **Explore** | Fast codebase Q&A; uses GitHub MCP tools | Codebase analysis prompts | -| **Task** | Run commands smartly | Command execution prompts | -| **Plan** | Implementation planning | Planning prompts | -| **Code-review** | High-signal reviews | Review prompts | +| **Explore** | Fast codebase Q&A; read-only GitHub MCP tools | Automatic | +| **Task** | Run tests, builds, linters | Automatic | +| **General-purpose** | Main-agent capabilities in a separate context | Automatic | +| **Code-review** | High-signal diff reviews | Automatic / `/review` | +| **Rubber-duck** | Critique on a complementary model | Automatic / `/rubber-duck` | +| **Security-review** | 11 vulnerability categories | `/security-review` | | **Research** | Deep investigations | `/research` | -| **Fleet** | Parallel subagent orchestration | `/fleet` | -| **Rubber-duck** | Critique plans and implementations | Feedback prompts | +| **REM** | Memory consolidation | Background | + +**Plan** and **fleet** are session *modes*, not agents --- ## Agent Hierarchy ``` -User agents (~/.config/copilot/agents/) โ† highest priority +User agents (~/.copilot/agents/) โ† highest priority โ†“ Enterprise agents (.github-private repo) โ†“ Organization agents (.github-private repo) โ†“ -Repository agents (.github/agents/) +Repository agents (.github/agents/ or .claude/agents/) โ†“ AGENTS.md (root or subdirectory) ``` @@ -146,17 +182,21 @@ Agents can **delegate to other agents** for complex workflows --- -## configure-copilot Sub-Agent +## Configure from Inside a Session -Built-in agent that manages configuration for you: +Manage everything without leaving the CLI: -``` -Help me set up an MCP server for PostgreSQL -``` +| Command | Manages | +|---------|---------| +| `/agent` | Custom agents | +| `/mcp` | MCP servers | +| `/skills` | Skills | +| `/plugin` | Plugins and marketplaces | +| `/subagents` | Per-agent model, effort, context tier | +| `/settings` | User settings (`--repo` / `--local` for repo scope) | -- Manages **MCP servers**, **custom agents**, and **skills** -- Modifies config files on your behalf -- Human-readable sub-agent IDs (e.g., `math-helper-0`) +> User settings live in `~/.copilot/settings.json`. +> `~/.copilot/config.json` is managed automatically and holds credentials โ€” never print it. --- @@ -174,4 +214,4 @@ Open **Module 8** in `docs/workshop/08-custom-agents.md` - **Exercise 6** โ€” Subagents & delegation - **Exercise 7** โ€” Debugging agent config -โฑ๏ธ You have **~8 minutes** +โฑ๏ธ You have **~16 minutes** diff --git a/docs/slides/09-hooks.md b/docs/slides/09-hooks.md index 4275c78..dbb4af7 100644 --- a/docs/slides/09-hooks.md +++ b/docs/slides/09-hooks.md @@ -77,27 +77,56 @@ Use cases: **logging**, **security guardrails**, **auditing**, **alerts** | Hook | Trigger | Common use | |------|---------|-----------| -| `sessionStart` | Session begins | Logging, setup | -| `sessionEnd` | Session ends | Cleanup, metrics | +| `sessionStart` / `sessionEnd` | Session starts/resumes, ends | Logging, cleanup | | `userPromptSubmitted` | User sends prompt | Audit trail | +| `userPromptTransformed` | Prompt turned into model-facing form | Prompt rewriting | | `preToolUse` | Before tool runs | **Permission control** | +| `preMcpToolCall` | Before an MCP tool request is sent | Adjust MCP metadata | | `postToolUse` | After successful tool run | Verification, logging | | `postToolUseFailure` | After tool failure | Error handling | -| `errorOccurred` | Error happens | Alerts, monitoring | +| `errorOccurred` | A model call fails | Alerts, monitoring | | `preCompact` | Before compaction | State saving | -| `subagentStart` | Sub-agent spawned | Context injection | +| `agentStop` | Agent stops at end of turn | Turn-level automation | +| `subagentStart` / `subagentStop` | Sub-agent spawned / completed | Context injection, results | | `permissionRequest` | Permission requested | Programmatic approve/deny | | `notification` | Shell/agent completion, permissions | External notifications | --- +## โš ๏ธ Trust Is Required + +**Repository hooks only run in trusted folders** + +- Answer **Yes, and remember** at the trust prompt +- Or add the path to `trustedFolders` + +In an untrusted folder, `.github/hooks/*.json` is discovered but **never executed** โ€” and **no error is shown** + +Personal hooks in `~/.copilot/hooks/` run regardless of trust + +**Do this before Exercise 1.** + +--- + +## Hook Locations + +| Scope | Location | +|-------|----------| +| **Repository** | any `*.json` in `/.github/hooks/` | +| **Personal** | any `*.json` in `~/.copilot/hooks/` | +| **Inline** | the `hooks` key in settings | + +Turn hooks off with `disableAllHooks`, or suppress individual ones with `disabledHooks` +(policy hooks ignore both) + +--- + ## Configuration -Lives at `.github/hooks/hooks.json` +Lives in any `*.json` file under `.github/hooks/` โ€” e.g. `hooks.json` ```json { - "version": 1, "hooks": { "preToolUse": [ { @@ -113,6 +142,19 @@ Lives at `.github/hooks/hooks.json` --- +## Payload Shape Follows the Key + +The event key's casing decides the payload โ€” the two shapes never mix + +| Event key | Payload fields | +|-----------|----------------| +| camelCase `preToolUse` | `sessionId`, `timestamp` (ms), `cwd`, `toolName`, `toolArgs` (JSON **string**) | +| PascalCase `PreToolUse` | `hook_event_name`, `session_id`, `timestamp` (ISO 8601), `cwd`, `tool_name`, `tool_input` (JSON **object**) | + +Use **camelCase** for Copilot CLI; use **PascalCase** to reuse a VS Code or Claude Code hooks file + +--- + ## Session Logging Track session start/end with `sessionStart` and `sessionEnd` @@ -140,7 +182,26 @@ Track session start/end with `sessionStart` and `sessionEnd` ## Pre-Tool Permission Control -Block dangerous operations with `preToolUse` +`preToolUse` supports **three** permission decisions + +| Decision | Behavior | +|----------|----------| +| `allow` | Allow the tool to execute | +| `deny` | Block the tool with a reason | +| `ask` | Prompt the user for confirmation before executing | + +```json +{ + "permissionDecision": "allow|deny|ask", + "permissionDecisionReason": "Explanation shown to user" +} +``` + +> `ask` lets hooks request confirmation instead of silently allowing or denying + +--- + +## Blocking a Dangerous Command ```bash INPUT=$(cat) @@ -158,6 +219,29 @@ echo '{}' --- +## Reshaping the Tool Call + +`preToolUse` hooks can also return these fields โ€” the CLI respects them + +| Field | Effect | +|-------|--------| +| `modifiedArgs` | Replace the tool arguments (JSON string) | +| `updatedInput` | Replace the prompt text | +| `additionalContext` | Inject extra context for the turn | + +```json +{ + "modifiedArgs": "{\"command\": \"ls -la --color=never\"}", + "updatedInput": "Modified prompt text", + "additionalContext": "Extra context injected by hook" +} +``` + +> Return only `permissionDecision`/`permissionDecisionReason` or the fields +> above โ€” other keys are ignored + +--- + ## Post-Tool Logging Log tool results with `postToolUse` @@ -178,8 +262,10 @@ echo "[$(date -Iseconds)] $TOOL_NAME: $RESULT" >> logs/audit.log Open **Module 9** in `docs/workshop/09-hooks.md` +> **First:** make sure your folder is trusted, or none of the repository hooks will run. + **Exercises 1-7:** -1. **Exercise 1** โ€” Create hooks skeleton +1. **Exercise 1** โ€” Trust the folder + create hooks skeleton 2. **Exercise 2** โ€” Session logging hooks 3. **Exercise 3** โ€” Prompt auditing hook 4. **Exercise 4** โ€” Pre-tool permission control diff --git a/docs/slides/10-context.md b/docs/slides/10-context.md index ed05c34..2d6a88e 100644 --- a/docs/slides/10-context.md +++ b/docs/slides/10-context.md @@ -88,6 +88,10 @@ copilot --context long_context copilot help config ``` +Persist it with `"contextTier": "long_context"` in `~/.copilot/settings.json` + +> `~/.copilot/config.json` is managed automatically and holds credentials โ€” never print it. + Available models and context windows depend on your subscription and selected model. --- @@ -99,7 +103,8 @@ Available models and context windows depend on your subscription and selected mo | `/context` | Show token usage | Check regularly | | `/usage` | Session stats (requests, duration, lines edited) | Track consumption | | `/compact` | Compress history | Long sessions | -| `/clear` | Reset everything | Switching topics | +| `/clear` | Abandon session and start fresh (session is discarded) | Abandoning session entirely | +| `/new` | Start new conversation (old session stays backgrounded) | New topic, keep old session | | `/cwd` | Change working directory | Switch project scope | | `@path/to/file` | Include file in prompt | Targeted context | | `#` | Include issue/PR/discussion | GitHub context | @@ -130,7 +135,8 @@ Show me just @src/auth/middleware.ts | Strategy | When | |----------|------| -| `/clear` | Switching to unrelated topic | +| `/clear` | Abandoning session entirely | +| `/new` | Starting new topic but keeping old session accessible | | `/compact` | Long session, need to continue | | Explore agent | Codebase overview without cost | | `@path/to/file` | Include specific files | diff --git a/docs/slides/11-sessions.md b/docs/slides/11-sessions.md index 5195735..ba5c954 100644 --- a/docs/slides/11-sessions.md +++ b/docs/slides/11-sessions.md @@ -91,12 +91,31 @@ copilot prompts + tools /exit or Ctrl+C | `/session` | Show session info (ID, duration, files) | | `/usage` | Token consumption and API calls | | `/rename NAME` | Name your session for easy finding | -| `/clear` | Abandon session and start fresh | +| `/clear` | Abandon session and start fresh (session is discarded) | +| `/new` | Start new conversation (old session stays backgrounded) | | `/resume` | Switch to a previous session | | `--continue` | Resume most recent session from CLI | | `/share` | Export to markdown or GitHub Gist | -| `/undo` | Undo last turn when possible | -| `/rewind` | Roll back through session timeline | +| `/rewind` (alias `/undo`) | Rewind the last turn and revert file changes | + +--- + +## Session Data on Disk + +| Path | Contents | +|------|----------| +| `~/.copilot/session-state//` | Transcript, checkpoints, rewind snapshots | +| `~/.copilot/session-store.db` | Index used by `/session`, `/resume`, `--resume` | + +Manage it with subcommands, not `rm`: + +``` +/session info # details about this session +/session checkpoints # list checkpoints +/session files # files touched +/session prune # prune old session data +/session delete-all # delete every session +``` --- @@ -120,15 +139,17 @@ Copilot can only access directories you've allowed --- -## When to Clear vs Compact +## When to Clear, Compact, or Start New -| Situation | Action | +| Scenario | Action | |-----------|--------| -| Switching to unrelated task | `/clear` | -| Confused or wrong responses | `/clear` | -| Context getting full | `/compact` first | -| Sensitive info discussed | `/clear` + `/exit` | -| Session becoming slow | `/clear` | +| Switching to unrelated task | `/new` (keeps old session) or `/clear` (abandons) | +| Confused responses | `/new` | +| Context limit approaching | `/compact` first, then `/new` if needed | +| Sensitive info discussed | `/clear` and `/exit` | +| Session becomes slow | `/new` | + +> `/clear` **abandons** the session โ€” `/new` keeps it **backgrounded** --- diff --git a/docs/slides/12-advanced.md b/docs/slides/12-advanced.md index b867899..6af6c0c 100644 --- a/docs/slides/12-advanced.md +++ b/docs/slides/12-advanced.md @@ -68,7 +68,7 @@ style: | | **ACP** | Agent Client Protocol server | | **CI/CD** | Pipeline integration | | **Environment** | Config, env vars, `--bash-env` | -| **LSP** | Language server timeout config | +| **LSP** | Language server configuration | | **Research & Chronicle** | Deep research, session insights | | **Team workflows** | Standardization patterns | @@ -147,9 +147,10 @@ Key flags for automation: `--silent`, `--allow-tool`, `--deny-tool` | File | Purpose | |------|---------| -| `~/.copilot/config.json` | User settings, trusted folders | +| `~/.copilot/settings.json` | User settings | +| `~/.copilot/config.json` | Machine-managed state + credentials โ€” **do not print** | | `~/.copilot/mcp-config.json` | MCP servers | -| `~/.copilot/lsp.json` | Language server timeouts | +| `~/.copilot/lsp-config.json` | Language server definitions | ```bash # Source custom env in shell sessions @@ -166,6 +167,74 @@ export GITHUB_TOKEN="github_pat_..." # lowest priority --- +## BYOK & Offline Mode + +**Bring Your Own Key** โ€” set `COPILOT_PROVIDER_BASE_URL` to activate BYOK mode with a custom model provider. GitHub authentication is not required when using a custom provider. + +```bash +# Ollama (local, no API key required) +COPILOT_PROVIDER_BASE_URL=http://localhost:11434/v1 \ + COPILOT_MODEL=local-code-model \ + copilot +``` + +**Offline mode** โ€” `COPILOT_OFFLINE=true` skips all network access: GitHub authentication, telemetry, web tools, GitHub MCP server, and auto-update are disabled. Requires a local model provider. + +> `copilot help providers` documents Azure, Anthropic, and OpenAI-compatible providers + +--- + +## Language Servers + +None run by default โ€” define them explicitly + +```json +{ + "lspServers": { + "typescript": { + "command": "typescript-language-server", + "args": ["--stdio"], + "fileExtensions": { ".ts": "typescript", ".tsx": "typescriptreact" } + } + } +} +``` + +`~/.copilot/lsp-config.json` (personal) ยท `.github/lsp.json` (project) + +``` +/lsp show # configured servers +/lsp test NAME # does it start? +/lsp reload # reload from disk +/lsp logs # live status + server logs +``` + +--- + +## Help Topics & Session Limits + +```bash +copilot help billing | commands | config | environment | limits +copilot help logging | monitoring | permissions | providers | sandbox +``` + +**Session limits are opt-in** โ€” a soft cap on AI credits + +```bash +copilot --max-ai-credits 30 # minimum is 30 +``` + +``` +/limits # interactive dialog +/limits set max-ai-credits 50 +/limits predict +/limits unset max-ai-credits +``` + +> `/clear` and `/new` reset used credits but keep the limit + +--- + ## Useful Aliases ```bash @@ -189,9 +258,12 @@ alias cop-resume='copilot --resume' **`/chronicle`** (experimental) โ€” session-history insights: ``` -/chronicle standup # what you accomplished -/chronicle tips # feature suggestions -/chronicle improve # workflow improvements +/chronicle standup # your work from the last day +/chronicle search # search all session content +/chronicle tips # personalized usage tips +/chronicle cost-tips # reduce token usage and cost +/chronicle improve # improve copilot-instructions.md +/chronicle reindex # reload the session store index ``` > โš ๏ธ `/chronicle` is experimental โ€” subcommands may change @@ -208,21 +280,10 @@ Open **Module 12** in `docs/workshop/12-advanced.md` - **Exercise 2** โ€” CI/CD integration - **Exercise 3** โ€” Advanced CLI flags - **Exercise 4โ€“5** โ€” Autopilot mode & fleet command -- **Exercise 6โ€“7** โ€” Shell config & LSP setup -- **Exercise 8โ€“11** โ€” Config, troubleshooting & team workflows +- **Exercise 6** โ€” Shell config & `--bash-env` +- **Exercise 7** โ€” Language server configuration +- **Exercise 8โ€“10** โ€” Settings, troubleshooting & team workflows +- **Exercise 11** โ€” Performance optimization - **Exercise 12** โ€” `/research` deep research & `/chronicle` insights โฑ๏ธ You have **~24 minutes** - ---- - -# ๐ŸŽ‰ Workshop Complete! - -### What you've learned across all modules: - -Installation โ†’ Modes โ†’ Sessions โ†’ Instructions โ†’ Tools -โ†’ MCP โ†’ Skills โ†’ Plugins โ†’ Agents โ†’ Hooks โ†’ Context โ†’ Advanced - -**Next steps:** Practice daily, create custom agents, share skills with your team - -> Resources: [docs.github.com/copilot](https://docs.github.com/en/copilot) ยท [agentskills.io](https://agentskills.io) diff --git a/docs/slides/13-configuration.md b/docs/slides/13-configuration.md index 2bf9119..9c42f3f 100644 --- a/docs/slides/13-configuration.md +++ b/docs/slides/13-configuration.md @@ -61,19 +61,19 @@ style: | ## Topics -- Configuration file (`config.json`) options +- User settings (`settings.json`) and settings scopes - Environment variables reference - CLI flags quick reference - IDE integration (`/ide`, `openDiffOnEdit`) - Accessibility & streamer mode - Team configuration standardization -- Logging and debugging +- Logging, debugging, and session limits --- ## Configuration File -All settings live in `~/.copilot/config.json`: +User settings live in `~/.copilot/settings.json`: ```json { @@ -90,6 +90,21 @@ All settings live in `~/.copilot/config.json`: Override location: `COPILOT_HOME` env var +> โš ๏ธ `~/.copilot/config.json` is machine-managed and holds your auth token โ€” **never print or share it** + +--- + +## Settings Scopes + +| Scope | Location | Set with | +|-------|----------|----------| +| User | `~/.copilot/settings.json` | `/settings ` | +| Repo (shared) | `.github/copilot/settings.json` | `/settings --repo ...` | +| Repo (personal) | `.github/copilot/settings.local.json` | `/settings --local ...` | +| Org-managed | Delivered by policy | Read-only, `managed (read-only)` | + +Managed settings apply on top of yours and cannot be edited from the CLI + --- ## Key Config Options @@ -104,6 +119,10 @@ Override location: `COPILOT_HOME` env var | `companyAnnouncements` | `[]` | Team startup messages | | `ide.autoConnect` | `true` | Auto-connect to IDE | | `ide.openDiffOnEdit` | `true` | Diffs in IDE | +| `footer.show*` | (varies) | Individual status bar items | +| `sandbox.*` | (varies) | Command sandboxing policy | + +> `copilot help config` is the authoritative reference --- @@ -116,10 +135,14 @@ Override location: `COPILOT_HOME` env var | `COPILOT_MODEL` | Default model | | `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` | Extra instruction dirs | | `COPILOT_EDITOR` | Editor for plans/prompts | +| `COPILOT_PROVIDER_*` | Custom model provider (BYOK) | +| `COPILOT_OTEL_*` / `OTEL_*` | OpenTelemetry monitoring | | `PLAIN_DIFF` | Disable rich diffs | | `USE_BUILTIN_RIPGREP` | Set `false` to use PATH ripgrep | | `NO_COLOR` | Disable color output | +> `copilot help environment` is the authoritative reference + --- ## Additional CLI Flags @@ -150,12 +173,12 @@ Override location: `COPILOT_HOME` env var ``` /ide # Connect to IDE workspace /copy # Copy last response to clipboard -config.json: "streamerMode": true +/settings streamerMode on ``` Config options: -- `ide.autoConnect` -- auto-connect on startup -- `ide.openDiffOnEdit` -- show diffs in IDE +- `ide.autoConnect` โ€” auto-connect on startup +- `ide.openDiffOnEdit` โ€” show diffs in IDE --- @@ -172,17 +195,60 @@ Config options: } ``` -Distribute via shared config templates in your repo. +Share via repository settings: + +``` +/settings --repo model auto # .github/copilot/settings.json +/settings --local theme dim # settings.local.json (uncommitted) +``` + +--- + +## Session Limits + +Opt-in soft cap on AI credits for a session + +```bash +copilot --max-ai-credits 30 # minimum is 30 +``` + +``` +/limits # interactive dialog +/limits set max-ai-credits 50 +/limits predict +/limits unset max-ai-credits +``` + +> Usage is only known after a response returns, so one call can +> exceed the limit before the next one is blocked --- -## Your Turn! +## Your Turn! ๐Ÿš€ + +Open **Module 13** in `docs/workshop/13-configuration.md` + +**Start from Exercise 1** and work through as many as you can + +- **Exercise 1** โ€” Explore settings.json and settings scopes +- **Exercise 2** โ€” Environment variable control +- **Exercise 3** โ€” IDE integration +- **Exercise 4** โ€” Streamer mode & accessibility +- **Exercise 5** โ€” Team configuration +- **Exercise 6** โ€” Logging and debugging +- **Exercise 7** โ€” Session limits and AI credits + +โฑ๏ธ You have **~14 minutes** + +--- + +# ๐ŸŽ‰ Workshop Complete! + +### What you've learned across all modules: + +Installation โ†’ Modes โ†’ Instructions โ†’ Tools โ†’ MCP โ†’ Skills โ†’ Plugins +โ†’ Agents โ†’ Hooks โ†’ Context โ†’ Sessions โ†’ Advanced โ†’ Configuration -### Recommended exercises from Module 13: +**Next steps:** Practice daily, create custom agents, share skills with your team -1. **Exercise 1** -- Explore config.json options -2. **Exercise 2** -- Environment variable control -3. **Exercise 3** -- IDE integration -4. **Exercise 4** -- Streamer mode & accessibility -5. **Exercise 5** -- Team configuration -6. **Exercise 6** -- Logging and debugging +> Resources: [docs.github.com/copilot](https://docs.github.com/en/copilot) ยท [agentskills.io](https://agentskills.io) diff --git a/docs/workshop/00-index.md b/docs/workshop/00-index.md index d6fd4e6..80da4c2 100644 --- a/docs/workshop/00-index.md +++ b/docs/workshop/00-index.md @@ -94,9 +94,11 @@ copilot --continue | --- | --- | | `/help` | Show all available commands | | `/ask` | Ask a quick question without affecting conversation history | +| `/refine` | Rewrite a rough prompt into a clear one for review | | `/clear` | Abandon session and start fresh | | `/new` | Start new conversation (old session stays backgrounded) | | `/session` | View and manage sessions | +| `/fork` | Fork the current session into a new session | | `/usage` | Display session usage metrics | | `/context` | View token usage | | `/compact` | Compress session history | @@ -113,12 +115,12 @@ copilot --continue | `/init` | Initialize Copilot config for repo | | `/instructions` | View and toggle custom instruction files | | `/allow-all` | Enable all permissions during the session | +| `/permissions` | Switch between permission modes (`manual`, `assisted`, `allow-all`, `show`) | | `/add-dir` | Add a directory to the session access scope | | `/list-dirs` | Display all accessible directories | | `/cwd` | Change working directory | | `/research` | Deep research with exportable reports | -| `/undo` | Undo the last turn when possible | -| `/rewind` | Roll back to any point in conversation history | +| `/rewind` (alias `/undo`) | Rewind the last turn and revert file changes (also via double-Esc) | | `/copy` | Copy last response to clipboard | | `/ide` | Connect to IDE workspace | | `/lsp` | Manage language server configuration | @@ -130,6 +132,8 @@ copilot --continue | `/tasks` | View and manage tasks (subagents and shell commands) | | `/env` | Show loaded instructions, MCP servers, skills, agents, hooks, plugins, LSPs, and extensions | | `/settings` | Open or edit CLI settings | +| `/statusline` | Configure status line items | +| `/changelog` | Display the changelog for CLI releases | | `/subagents` | Configure default and per-agent subagent models | ## Environment Setup Check diff --git a/docs/workshop/01-installation.md b/docs/workshop/01-installation.md index 8154d5d..8f903cb 100644 --- a/docs/workshop/01-installation.md +++ b/docs/workshop/01-installation.md @@ -35,7 +35,7 @@ Copilot CLI supports multiple installation methods: | --- | --- | --- | | **Script** | `curl -fsSL https://gh.io/copilot-install \| bash` | Quick setup | | npm | `npm install -g @github/copilot` | Node.js developers | -| Homebrew | `brew install copilot-cli` | macOS/Linux users | +| Homebrew (cask) | `brew install --cask copilot-cli` | macOS users | | WinGet | `winget install GitHub.Copilot` | Windows users | | Dev Container | Built-in | Codespaces users | @@ -60,6 +60,13 @@ copilot version Inside an interactive session, use `/version` to display version information and check for updates. +`copilot update` follows the stable channel. To choose a channel explicitly: + +```bash +copilot update stable +copilot update prerelease +``` + ### Shell Completion Enable tab completion for `copilot` subcommands and flags: @@ -156,7 +163,7 @@ GitHub Copilot CLI GitHub Copilot CLI ``` -### Exercise 1c: Install via Homebrew (macOS/Linux) option +### Exercise 1c: Install via Homebrew (macOS) option **Goal:** Install using Homebrew package manager. @@ -171,9 +178,11 @@ GitHub Copilot CLI 2. Install Copilot CLI: ```bash - brew install copilot-cli + brew install --cask copilot-cli ``` + > **Note:** Copilot CLI ships as a Homebrew **cask**, so it is available on macOS. The unrelated `copilot` *formula* is a different project โ€” always install the `copilot-cli` cask. + 3. Verify installation: ```bash @@ -228,9 +237,9 @@ GitHub Copilot CLI 2. When prompted, press Enter to authenticate. -3. A browser window opens. Sign in to GitHub if needed. +3. Copilot starts the OAuth flow. On a local desktop it opens your browser and captures the result on a loopback callback. In remote or headless environments (SSH, Codespaces, dev containers, CI, headless Linux) it uses the device code flow instead. Force a mode with `copilot login --web-flow` or `copilot login --device-code`. -4. Authorize the application when prompted. +4. Sign in to GitHub if needed, and authorize the application when prompted. 5. Return to your terminal. You should see the Copilot prompt: @@ -280,6 +289,8 @@ Copilot correctly identifies your working directory and shows available commands | `/logout` shows warning | When signed in via gh CLI, PAT, API key, or env var, `/logout` displays a warning explaining that the credential source must be removed separately | | Auto-update interfering | Disable with `--no-auto-update` or set `COPILOT_AUTO_UPDATE=false` | | Auth fails in Docker/container | Use fine-grained PAT auth: `export GH_TOKEN="github_pat_..."`. See [Authentication in Containers](#authentication-in-containers-and-cicd) below | +| Classic PAT rejected | Classic personal access tokens (`ghp_`) are not supported. Use a fine-grained PAT with the "Copilot Requests" permission | +| Browser never opens on a remote host | Remote and headless environments use the device code flow. Run `copilot login --web-flow` to force the browser flow, or `copilot login --device-code` to request the device code explicitly | ### Fixing npm Permissions @@ -336,13 +347,15 @@ This stores credentials separately from github.com, allowing you to connect to y ## Summary - โœ… Copilot CLI requires current Node.js LTS for npm installation -- โœ… Multiple installation methods: npm, Homebrew, script, WinGet -- โœ… Authentication uses GitHub OAuth in your browser +- โœ… Multiple installation methods: script, npm, Homebrew cask (macOS), WinGet +- โœ… Authentication uses GitHub OAuth: browser flow on local desktops, device code flow in remote and headless environments +- โœ… `copilot login --web-flow` and `copilot login --device-code` force a specific OAuth mode - โœ… GHEC data residency supported via `copilot login --host` - โœ… Organization members need admin-enabled CLI policy - โœ… Dev Containers and Codespaces include Copilot CLI by default - โœ… Auto-updates can be disabled with `--no-auto-update` - โœ… Use `--version`, `copilot version`, and `/version` to inspect the installed version +- โœ… `copilot update` takes a `stable` (default) or `prerelease` channel argument - โœ… `/logout` warns when credential source is external (gh CLI, PAT, env var) - โœ… Shell completion available for bash, zsh, and fish via `copilot completion` - โœ… Classic PATs are not supported โ€” use fine-grained PATs with "Copilot Requests" permission diff --git a/docs/workshop/02-modes.md b/docs/workshop/02-modes.md index c15517d..9b72b92 100644 --- a/docs/workshop/02-modes.md +++ b/docs/workshop/02-modes.md @@ -94,20 +94,20 @@ Slash commands are prefixed with `/` and provide quick access to CLI features wi | Category | Commands | Purpose | | --- | --- | --- | -| **Session** | `/clear`, `/new`, `/session`, `/resume`, `/rename`, `/usage` | Manage session lifecycle | +| **Session** | `/clear`, `/new`, `/session`, `/resume`, `/rename`, `/fork`, `/usage` | Manage session lifecycle | | **Navigation** | `/cwd`, `/add-dir`, `/list-dirs` | Control directory scope | | **Context** | `/context`, `/compact` | Monitor and optimize token usage | -| **Quick** | `/ask` | Ask a quick question without affecting conversation history | +| **Quick** | `/ask`, `/refine` | Ask a quick question or clean up a rough prompt | | **Environment** | `/env` | Show loaded environment details (instructions, MCPs, skills, plugins) | -| **Tools** | `/allow-all`, `/reset-allowed-tools` | Manage tool permissions at runtime | -| **Review** | `/diff`, `/review`, `/rubber-duck`, `/security-review`, `/plan`, `/research`, `/undo`, `/rewind` | Code review, critique, planning, history navigation | -| **Configuration** | `/model`, `/mcp`, `/plugin`, `/theme`, `/terminal-setup`, `/experimental`, `/instructions`, `/settings`, `/subagents` | Customize CLI behavior | -| **Extensibility** | `/skills`, `/plugin`, `/agent`, `/fleet` | Manage skills, plugins, agents, and parallel execution | +| **Tools** | `/permissions`, `/allow-all`, `/reset-allowed-tools` | Manage tool permissions at runtime | +| **Review** | `/diff`, `/review`, `/rubber-duck`, `/security-review`, `/plan`, `/research`, `/rewind` | Code review, critique, planning, history navigation | +| **Configuration** | `/model`, `/mcp`, `/plugin`, `/theme`, `/statusline`, `/terminal-setup`, `/experimental`, `/instructions`, `/settings`, `/subagents` | Customize CLI behavior | +| **Extensibility** | `/skills`, `/plugin`, `/agent`, `/fleet`, `/delegate` | Manage skills, plugins, agents, parallel execution, and cloud delegation | | **Scheduling** | `/after`, `/every` | Schedule one-shot or recurring prompts and skills | | **Sharing** | `/share`, `/share html`, `/feedback`, `/copy` | Export sessions, copy responses, and submit feedback | | **Account** | `/login`, `/logout`, `/user` | Authentication and user management | | **IDE** | `/ide` | Connect to IDE workspace | -| **System** | `/help`, `/exit`, `/init`, `/tasks`, `/lsp`, `/update`, `/restart`, `/chronicle`, `/search`, `/keep-alive`, `/limits`, `/diagnose`, `/app` | General utilities and productivity | +| **System** | `/help`, `/changelog`, `/exit`, `/init`, `/tasks`, `/lsp`, `/update`, `/restart`, `/version`, `/voice`, `/chronicle`, `/search`, `/keep-alive`, `/limits`, `/diagnose`, `/app` | General utilities and productivity | #### Keyboard Shortcuts @@ -122,7 +122,7 @@ In addition to slash commands, Copilot CLI supports keyboard shortcuts: | `Double-Esc` | Clear input when text is present; trigger undo when prompt is empty | | `ctrl+x โ†’ /` | Run a slash command | | `ctrl+c` | Cancel operation / clear input / exit | -| `ctrl+d` | Shutdown / exit CLI on empty prompt | +| `ctrl+d` | Exit the CLI on an empty prompt; use `ctrl+q` or `ctrl+enter` to queue a message instead | | `ctrl+l` | Clear the screen | | `ctrl+n` | Navigate down (alternative to down arrow) | | `ctrl+p` | Navigate up (alternative to up arrow) | @@ -140,7 +140,6 @@ In addition to slash commands, Copilot CLI supports keyboard shortcuts: | `ctrl+f` | Page forward | | `ctrl+b` | Page back | | `ctrl+g` | Open current prompt in external editor; or dismiss dialog | -| `ctrl+d` | Exit prompt (no longer queues a message; use `Ctrl+Q` or `Ctrl+Enter` to queue) | | `Home` / `End` | Navigate within visual line; jump to top/bottom of scroll buffer | | `ctrl+Home` / `ctrl+End` | Jump to text boundaries | | `Shift+Tab` | Cycle through modes โ€” (chat) โ†’ (plan) โ†’ (autopilot) | @@ -181,9 +180,10 @@ Some commands are covered in depth in later modules (`/mcp` in Module 5, `/skill | `/init` | Initialize Copilot instructions and agentic features for a repository | | `/tasks` | View and manage background tasks (subagents, shell sessions) | | `/rename ` | Rename the current session for easy identification; omit name to auto-generate from conversation history | -| `/theme [show\|set\|list]` | View or configure the terminal color theme | +| `/settings theme ` | Set the color theme (`default`, `github`, `dim`, `high-contrast`, `colorblind`); `/theme` with no argument opens the theme picker | +| `/statusline` | Configure which items appear in the status line (for example `quota` and `ai-used`) | | `/terminal-setup` | Configure terminal for multiline input support (shift+enter) | -| `/lsp` | View configured Language Server Protocol servers | +| `/lsp` | Manage language server configuration โ€” view and configure Language Server Protocol servers | | `/user [show\|list\|switch]` | Manage GitHub user list (multi-account support) | | `/update` | Update the CLI | | `/research [prompt]` | Perform deep research with exportable reports | @@ -192,22 +192,66 @@ Some commands are covered in depth in later modules (`/mcp` in Module 5, `/skill | `/ide` | Connect to an IDE workspace (VS Code, etc.) for diagnostics and diff review | | `/restart` | Hot restart the CLI while preserving your session | | `/version` | Display CLI version and check for updates | -| `/undo` | Undo the last turn when possible | -| `/rewind` | Open a timeline picker to roll back to any point in conversation history (also via double-Esc) | +| `/voice` | Manage voice mode โ€” dictation transcription via Foundry Local | +| `/rewind` (alias `/undo`) | Rewind the last turn and revert file changes; also available via double-Esc | +| `/fork [name]` | Fork the current session into a new session, optionally with a name | +| `/refine` | Rewrite a rough, stream-of-consciousness prompt into a clear one for review (`ctrl+x โ†’ /` then `/refine` cleans up your current input) | +| `/permissions [manual\|assisted\|allow-all\|show]` | Switch between permission modes, or show the current permission status | +| `/changelog [summarize]` | Display the changelog for CLI releases; add `summarize` for an AI summary | | `/new [prompt]` | Start a fresh conversation (keeps old session backgrounded); optionally provide a first message | | `/clear [prompt]` | Abandon the current session entirely; optionally provide a first message for the new session | | `/allow-all [on\|off\|show]` | Enable, disable, or check allow-all (YOLO) mode | | `/share html` | Export session as a self-contained interactive HTML file | | `/keep-alive [on\|off\|busy]` | Manage keep-alive mode โ€” prevents system sleep while session is active | | `/search` | Search the conversation timeline | -| `/limits` | View or edit session limits, including AI credit limits | +| `/limits` | View or edit session limits, including AI credit limits (see [Session Limits](#session-limits) below) | | `/memory [on\|off]` | Show or change cross-session memory status | | `/pr` | Operate on pull requests for the current branch | -| `/lsp` | Manage language server configuration | | `/subagents` | Configure default and per-agent subagent models | | `/after ` | Schedule a one-shot prompt or skill to run later | | `/every ` | Schedule a recurring prompt or skill | +#### Command Aliases + +Many commands accept a shorter or more familiar alias. Both forms behave identically: + +| Command | Alias | Command | Alias | +| --- | --- | --- | --- | +| `/allow-all` | `/yolo` | `/resume` | `/continue` | +| `/ask` | `/btw` | `/rewind` | `/undo` | +| `/changelog` | `/release-notes` | `/search` | `/find` | +| `/clear` | `/reset` | `/session` | `/sessions` | +| `/cwd` | `/cd` | `/settings` | `/config` | +| `/every` | `/loop` | `/share` | `/export` | +| `/exit` | `/quit` | `/skills` | `/skill` | +| `/feedback` | `/bug` | `/statusline` | `/footer` | +| `/fork` | `/branch` | `/subagents` | `/agents` | +| `/keep-alive` | `/caffeinate` | `/update` | `/upgrade` | +| `/model` | `/models` | | | + +#### Session Limits + +Session limits are opt-in and cap how many AI credits a session may consume. Usage accumulates across the whole session in both interactive and non-interactive runs, and subagents share the parent session's limit. + +Set an initial limit at launch: + +```bash +copilot --max-ai-credits 30 +``` + +Manage limits from inside a session: + +| Command | Description | +| --- | --- | +| `/limits` | Open the interactive limits dialog for the current session | +| `/limits set max-ai-credits ` | Set the AI credit limit (minimum 30) | +| `/limits unset [max-ai-credits\|all]` | Remove a specific limit, or all limits | + +> [!NOTE] +> The AI credit limit is a **soft cap**. Usage is known only after a model response returns, so a single response can exceed the limit before the CLI observes it โ€” the *next* model call is then blocked. Hidden model work such as compaction also counts toward the limit. In interactive sessions, `/clear` starts a fresh accounting window: used credits reset while the configured limit stays in effect. +> +> Run `copilot help limits` and `copilot help billing` from your shell for the full reference on limits and AI credit usage. + #### Commands Available During Agent Work | Command | Description | @@ -226,9 +270,19 @@ Some commands are covered in depth in later modules (`/mcp` in Module 5, `/skill | `--plan` | Start CLI directly in plan mode | | `--agent ` | Start with a specific agent, such as `rubber-duck` for high-signal critique | | `-n, --name ` | Set a name for the new session | +| `--session-id ` | Resume an existing session or task by ID, or set the UUID for a new session | +| `-C ` | Change working directory before doing anything else | +| `--context ` | Set the context window tier, overriding the persisted setting (`default`, `long_context`) | +| `--effort, --reasoning-effort ` | Set the reasoning effort level (`none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`) | +| `--max-ai-credits ` | Set the max AI credits for this session (minimum 30) | +| `--max-autopilot-continues ` | Maximum number of continuation messages in autopilot mode (default: 5) | +| `--experimental` / `--no-experimental` | Enable or disable experimental features | | `--connect[=sessionId]` | Connect directly to a remote session (optionally specify session ID or task ID) | -| `--remote` | Start a remote control session | +| `--remote` | Enable remote control of your session from GitHub web and mobile | | `--enable-reasoning-summaries` | Request reasoning summaries for OpenAI models | +| `--acp` | Start as an Agent Client Protocol server | + +> Run `copilot --help` for the complete list of flags, or see [Module 13](13-configuration.md#cli-flags-quick-reference) for the full flag reference. #### Rubber-Duck Feedback Mode @@ -287,14 +341,14 @@ The security review focuses on high-confidence security findings rather than gen 3. Review the output โ€” you'll see commands grouped with descriptions. -4. Try the `/theme` command to see available themes: +4. Open the theme picker to see available themes: ``` - /theme list + /theme ``` -5. Set a theme (optional): +5. Apply a theme by name: ``` - /theme set + /settings theme dim ``` 6. Check your current working directory: @@ -684,7 +738,13 @@ You can choose the appropriate mode for any task. - โœ… `/rubber-duck` starts a critique-focused feedback turn inside an interactive session - โœ… `--agent rubber-duck` starts a critique-focused feedback session - โœ… `/after` and `/every` schedule one-shot and recurring prompts -- โœ… `/undo` undoes the last turn when possible +- โœ… `/rewind` (alias `/undo`, or double-Esc) rewinds the last turn and reverts file changes +- โœ… `/permissions` switches between `manual`, `assisted`, and `allow-all` permission modes +- โœ… `/fork` branches the current session into a new one +- โœ… `/refine` rewrites a rough prompt into a clear one for review +- โœ… `/settings theme ` sets the color theme; `/theme` opens the theme picker +- โœ… `/limits` manages opt-in AI credit limits โ€” a soft cap, minimum 30 credits +- โœ… Most commands have aliases, such as `/yolo` for `/allow-all` and `/cd` for `/cwd` - โœ… `--remote` and `/remote` for remote control sessions - โœ… `/diff`, `/agent`, `/feedback`, and `/ide` work while agent is running - โœ… `Alt+D` deletes word forward in text input @@ -701,4 +761,4 @@ You can choose the appropriate mode for any task. - [Copilot CLI - GitHub Docs](https://docs.github.com/copilot/how-tos/copilot-cli) - [Use Copilot CLI - GitHub Docs](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli) -- [Copilot Coding Agent](https://docs.github.com/en/copilot/using-github-copilot/using-the-copilot-coding-agent) +- [Copilot Coding Agent](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/cloud-agent) diff --git a/docs/workshop/03-instructions.md b/docs/workshop/03-instructions.md index 45d566f..ec80b07 100644 --- a/docs/workshop/03-instructions.md +++ b/docs/workshop/03-instructions.md @@ -22,11 +22,13 @@ Copilot CLI reads instructions from multiple sources with this priority: ``` 1. Prompt (highest) - What you type -2. AGENTS.md - Nearest in directory tree +2. AGENTS.md - Nearest in directory tree (also CLAUDE.md and GEMINI.md, in git root and cwd) 3. .github/copilot-instructions.md - Repository-wide -4. .github/instructions/*.instructions.md - Path-specific -5. Personal instructions - ~/.copilot/instructions.md -6. Default behavior (lowest) +4. .github/instructions/**/*.instructions.md - Path-specific +5. Personal instructions - ~/.copilot/copilot-instructions.md +6. Personal path-specific - ~/.copilot/instructions/**/*.instructions.md +7. Additional directories - via COPILOT_CUSTOM_INSTRUCTIONS_DIRS +8. Default behavior (lowest) ``` ### File Purposes @@ -34,6 +36,8 @@ Copilot CLI reads instructions from multiple sources with this priority: | File | Scope | Purpose | | --- | --- | --- | | `AGENTS.md` | Directory tree | Agent persona and behavior | +| `CLAUDE.md` | Git root and cwd | Agent persona and behavior (cross-tool) | +| `GEMINI.md` | Git root and cwd | Agent persona and behavior (cross-tool) | | `copilot-instructions.md` | Repository | Coding standards and conventions | | `*.instructions.md` | File patterns | Language/path-specific rules | @@ -45,7 +49,7 @@ Use `/instructions` inside an interactive session to view and toggle which custo /instructions ``` -This displays all discovered instruction files (AGENTS.md, copilot-instructions.md, `*.instructions.md`, personal instructions) with their status. You can enable or disable individual files without deleting them โ€” useful for debugging which instructions are affecting behavior. +This displays all discovered instruction files (AGENTS.md, CLAUDE.md, GEMINI.md, copilot-instructions.md, `*.instructions.md`, and personal instructions from `~/.copilot/`) with their status. You can enable or disable individual files without deleting them โ€” useful for debugging which instructions are affecting behavior. | Action | Example | | --- | --- | @@ -481,6 +485,8 @@ Commit messages follow Conventional Commits format. - โœ… `copilot-instructions.md` sets repository-wide standards - โœ… `AGENTS.md` defines agent persona and boundaries +- โœ… `CLAUDE.md` and `GEMINI.md` are also read from the git root and cwd +- โœ… Personal instructions live at `~/.copilot/copilot-instructions.md` and `~/.copilot/instructions/**/*.instructions.md` - โœ… Path-specific instructions target file types with `applyTo` - โœ… Nested AGENTS.md files enable directory-specific behavior - โœ… Commit conventions should be explicitly documented diff --git a/docs/workshop/04-tools.md b/docs/workshop/04-tools.md index a02de2e..8032400 100644 --- a/docs/workshop/04-tools.md +++ b/docs/workshop/04-tools.md @@ -12,22 +12,33 @@ - Master the permission approval workflow - Use `--allow-tool` and `--deny-tool` flags effectively - Understand `--yolo` mode and when to use it safely +- Switch permission modes with `/permissions` +- Understand command sandboxing as an additional restriction layer - Configure trusted directories ## Concepts ### Built-in Tools -Copilot CLI includes several built-in tools: +Copilot CLI registers a set of built-in tools in every session: | Tool | Purpose | Risk Level | |------|---------|------------| -| `shell` | Execute shell commands | โš ๏ธ High | -| `write` | Create/modify files | โš ๏ธ High | -| `read` | Read file contents | Low | -| `show_file` | Present code/diffs to user in a prominent view | Low | -| `web_fetch` | Fetch web content | Medium | -| `mcp` | Use MCP server tools | Varies | +| `bash` | Execute shell commands (`read_bash`, `list_bash`, `stop_bash` manage background shells) | โš ๏ธ High | +| `create` / `edit` | Create files and make precise edits to existing files | โš ๏ธ High | +| `view` | Read files and list directories | Low | +| `glob` / `grep` | Find files by pattern and search file contents | Low | +| `web_fetch` / `web_search` | Fetch a URL and search the web | Medium | +| `fetch_copilot_cli_documentation` | Look up Copilot CLI's own documentation | Low | +| `task` / `read_agent` / `write_agent` / `list_agents` | Delegate work to subagents and exchange messages with them | Varies | +| `skill` | Load a skill's instructions on demand | Low | +| `sql` / `session_store_sql` | Query the agent's session database (to-do list, session history) | Low | +| `run_factory` | Run parallel agent factories (used by fleet mode) | Varies | +| `ask_user` | Ask you a clarifying question (interactive sessions; disable with `--no-ask-user`) | Low | +| MCP server tools | Tools contributed by configured MCP servers, prefixed with the server name | Varies | + +> [!NOTE] +> Permission rules match **kinds**, which are not the same as tool names. `copilot help permissions` defines exactly four kinds: `shell(command)`, `write(path)`, `(tool-name)`, and `url(domain-or-url)`. So `--allow-tool 'shell(git status)'` is a rule kind, while `bash` is the tool that runs the command. Use `--available-tools`/`--excluded-tools` when you need to filter by tool name. ### Permission Model @@ -70,6 +81,54 @@ Tool availability and tool permission are separate controls: Deny rules always take precedence over allow rules. +### Permission Modes + +`/permissions` switches the session between permission modes, and `/permissions show` reports the current one: + +| Mode | Behavior | +|---|---| +| `manual` | Require approval for each request | +| `assisted` | Approve requests an LLM safety check deems safe; prompt otherwise | +| `allow-all` | Auto-approve all tool, path, and URL requests | +| `show` | Display the current mode without changing it | + +Running `/permissions` with no argument opens the interactive mode picker. + +### Command Sandboxing + +Command sandboxing is a third layer alongside tool permissions and path permissions. When it is enabled, shell commands run inside an OS-level sandbox with restricted filesystem and network access, so a command the agent runs cannot reach outside the policy you configured. + +Sandboxing is an experimental feature: the `/sandbox` command is only registered when experimental features are on. Turn them on with the `--experimental` flag or `/settings experimental on`. + +```text +/sandbox # Show status; in interactive mode, opens the policy dialog +/sandbox enable # Turn command sandboxing on +/sandbox disable # Turn command sandboxing off +``` + +Sandboxing is powered by Microsoft Execution Containers (MXC), which maps the policy onto each platform's isolation primitives: Seatbelt (`sandbox-exec`) on macOS, bubblewrap (`bwrap`) on Linux, and ProcessContainer on Windows. If your host cannot run the backend, sandboxed shell commands fail rather than falling back to unsandboxed execution. + +Sandbox settings live under the `sandbox` key in `~/.copilot/settings.json` and can also be edited from the `/sandbox` dialog: + +| Setting | Purpose | +|---|---| +| `sandbox.enabled` | Whether command sandboxing is on | +| `sandbox.addCurrentWorkingDirectory` | Grant read/write access to the working directory | +| `sandbox.allowDevToolAccess` | Auto-grant the dev-tool caches and config that builds need | +| `sandbox.allowBypass` | Allow a per-command escape hatch out of the sandbox | +| `sandbox.gitAuth` / `sandbox.ghAuth` | Inject git and `gh` credentials into sandboxed commands | +| `sandbox.sandboxMcpServers` / `sandbox.sandboxLspServers` | Also sandbox local (stdio) MCP and LSP servers | +| `sandbox.userPolicy.filesystem.readwritePaths` / `readonlyPaths` / `deniedPaths` | Extra paths to grant or deny | +| `sandbox.userPolicy.network.allowOutbound` / `allowLocalNetwork` | Control outbound and local-network access | +| `sandbox.userPolicy.seatbelt.keychainAccess` | Allow system keychain access from inside the sandbox (macOS) | + +> [!NOTE] +> Remote (HTTP/SSE) MCP servers are never sandboxed. The sandbox also inherits your shell environment apart from a fixed blocklist, so credentials already exported in your environment remain visible to sandboxed commands โ€” use `--secret-env-vars` to strip the ones that matter. +> +> An organization policy can enforce sandboxing. When it does, `/sandbox disable` is refused and a local `sandbox.enabled: false` is overridden. + +Run `copilot help sandbox` for the full reference. + ## Hands-On Exercises ### Exercise 1: Understanding Tool Prompts @@ -95,7 +154,7 @@ Deny rules always take precedence over allow rules. ``` 4. Observe the tool approval prompt. It shows: - - Tool name: `write` + - Tool name: `create` (matched by the `write` permission kind) - File path: `test.txt` - Content preview - Three approval options @@ -326,15 +385,17 @@ You understand YOLO mode's power and risks. 3. Select **Yes, proceed** for now. -4. In a side terminal, check the config: +4. In a side terminal, check whether the folder was remembered. Read **only** the `trustedFolders` key: ```bash - cat ~/.copilot/config.json + grep -v '^[[:space:]]*//' ~/.copilot/config.json | jq -r '.trustedFolders[]?' ``` Notice that `trustedFolders` was **not** updated (you chose session-only trust). -5. To permanently skip the prompt for specific directories, add them to your config: - ```bash - # Edit config.json to add: + > [!WARNING] + > Never print, `cat`, or share the whole of `~/.copilot/config.json`. It is managed automatically by the CLI and stores your live Copilot authentication token alongside `trustedFolders`. Read only the specific key you need, as above โ€” especially while screen-sharing. Your own settings belong in `~/.copilot/settings.json`, which you can edit with `/settings`. + +5. To permanently skip the prompt for specific directories, add them to `~/.copilot/config.json`: + ```json { "trustedFolders": [ "/home/user/projects", @@ -342,7 +403,10 @@ You understand YOLO mode's power and risks. ] } ``` - Next time you launch Copilot from those directories, it won't ask for trust confirmation. + Next time you launch Copilot from those directories, it won't ask for trust confirmation. Choosing **Yes, and remember** at the trust prompt writes the same entry for you, which is the safer way to do it. + + > [!IMPORTANT] + > Folder trust also gates repository hooks: `.github/hooks/*.json` is discovered but never executed in an untrusted folder, and no error is shown. See [Module 9: Hooks](09-hooks.md). #### Part B: Runtime File Access @@ -546,14 +610,20 @@ copilot -p "Fix all linting errors" --allow-all-tools --no-ask-user | Command | Description | |---------|-------------| +| `/permissions [manual\|assisted\|allow-all\|show]` | Switch permission modes, or show the current one | +| `/allow-all` | Enable all permissions (tools, paths, and URLs) | | `/reset-allowed-tools` | Reset the list of tools approved during the session | | `/add-dir ` | Add a trusted directory for the session (supports relative paths like `./src`, `../sibling`) | | `/list-dirs` | View accessible directories | +| `/sandbox [enable\|disable]` | Show or change command sandboxing (requires experimental features) | ## Summary - โœ… Copilot requires approval for high-risk actions; some low-risk tools may be pre-approved by environment policy +- โœ… Built-in tools include `bash`, `create`, `edit`, `view`, `glob`, `grep`, `web_fetch`, `web_search`, `task`, and `skill` +- โœ… Permission rules match kinds โ€” `shell`, `write`, ``, and `url` โ€” not tool names - โœ… One-time vs session-wide approval gives granular control +- โœ… `/permissions` switches between `manual`, `assisted`, and `allow-all` modes - โœ… Use `/reset-allowed-tools` to clear session approvals - โœ… `--allow-tool` and `--deny-tool` enable automation - โœ… Deny rules take precedence over allow rules @@ -565,6 +635,8 @@ copilot -p "Fix all linting errors" --allow-all-tools --no-ask-user - โœ… `--no-ask-user` enables fully autonomous operation - โœ… Path permission dialog offers one-time approval - โœ… `/add-dir` accepts relative paths like `./src` and `../sibling` +- โœ… Command sandboxing adds an OS-level restriction layer on top of tool and path permissions +- โœ… `~/.copilot/config.json` is managed automatically and holds credentials โ€” never print or share it ## Next Steps diff --git a/docs/workshop/05-mcps.md b/docs/workshop/05-mcps.md index 545307f..eb4aaad 100644 --- a/docs/workshop/05-mcps.md +++ b/docs/workshop/05-mcps.md @@ -41,7 +41,7 @@ MCP server errors surface directly in session output and in MCP server details, - A tool invocation fails - Configuration is invalid -Use `/mcp` inside a session or `copilot mcp list` / `copilot mcp get ` from your shell to inspect configured servers and their status. +Use `/mcp` inside a session or `copilot mcp list` / `copilot mcp get ` from your shell to inspect configured servers and their status. `/mcp reload` restarts servers after you change configuration, and `/mcp auth ` re-runs authentication for a remote server. ### Server Types @@ -417,6 +417,15 @@ MCP server provides structured file access with defined boundaries. Any startup /mcp ``` +8. **Drive the same view with subcommands:** + ``` + /mcp list + /mcp show memory + /mcp disable memory + /mcp enable memory + /mcp reload + ``` + **Expected Outcome:** You can manage MCP servers without editing config files and inspect them interactively. @@ -572,9 +581,21 @@ MCP server names (the keys in `"mcpServers"`) support dots (`.`), slashes (`/`), ### Slash Commands +`/mcp` accepts subcommands as well as opening the interactive view: + | Command | Description | |---------|-------------| -| `/mcp` | Open the interactive MCP server view | +| `/mcp` (or `/mcp show`) | Open the MCP server configuration and status interface | +| `/mcp list` (or `/mcp ls`) | List attached MCP servers and their status | +| `/mcp show ` | Show server details and available tools | +| `/mcp add [server-name]` | Add a new MCP server (interactive wizard) | +| `/mcp edit ` | Edit an existing MCP server (interactive wizard) | +| `/mcp delete ` | Delete an MCP server | +| `/mcp enable ` | Enable a previously disabled server (persists across sessions) | +| `/mcp disable ` | Disable a server (persists across sessions) | +| `/mcp reload` | Reload MCP configuration and restart servers | +| `/mcp auth ` | Authenticate with a remote MCP server | +| `/mcp search [query]` | Search MCP servers from the registry | ### Shell Commands @@ -604,6 +625,7 @@ MCP server names (the keys in `"mcpServers"`) support dots (`.`), slashes (`/`), - โœ… `--additional-mcp-config` loads temporary servers - โœ… MCP config loads from user, workspace, plugin, and built-in sources - โœ… `copilot mcp` CLI command for managing servers from the command line +- โœ… `/mcp` takes subcommands: `list`, `show`, `add`, `edit`, `enable`, `disable`, `delete`, `reload`, `auth`, `search` - โœ… Remote server auto-retry on transient network failures - โœ… MCP OAuth HTTPS redirect URI via self-signed cert fallback diff --git a/docs/workshop/06-skills.md b/docs/workshop/06-skills.md index ba83dee..16e2995 100644 --- a/docs/workshop/06-skills.md +++ b/docs/workshop/06-skills.md @@ -43,12 +43,12 @@ Level 3: Resources โ†’ Copilot accesses supporting files (as needed) ### Built-in Skills -> Copilot CLI ships with a set of **built-in skills** that are always available without any configuration. These provide common capabilities out of the box: -> - Code generation and transformation patterns -> - Testing and validation workflows -> - Documentation generation +> Copilot CLI ships with built-in skills that are always available without any configuration: > -> Built-in skills are listed alongside project and personal skills in the `/skills` command output. They cannot be disabled but can be overridden by creating a project or personal skill with the same name. +> - `customize-cloud-agent` โ€” configuring the Copilot cloud agent environment, including `copilot-setup-steps.yml`, preinstalled tools and dependencies, runners, and settings +> - `github-pr-media` โ€” uploading an image or video to GitHub's user attachments API and embedding it in a pull request description or comment +> +> Built-in skills are listed alongside project and personal skills in `copilot skill list` and in the `/skills` view. They cannot be deleted with `copilot skill remove`, but they can be disabled (`copilot plugins disable --skill`, or `/plugins disable --skill `), and a project or personal skill with the same name overrides the built-in. ### Managing Skills from the Shell @@ -70,8 +70,14 @@ copilot skill add https://example.com/my-skill/SKILL.md # List all skills copilot skill list copilot skill list --json + +# Remove a personal or project skill by name, or unregister a custom directory +copilot skill remove my-skill +copilot skill remove ~/my-custom-skills ``` +Skills provided by a plugin or by the built-in set cannot be removed this way โ€” disable them instead. + Skills are discovered from project directories (`.github/skills/`, `.agents/skills/`, `.claude/skills/`), personal directories (`~/.copilot/skills/`, `~/.agents/skills/`), installed plugins, and custom directories added with `copilot skill add `. ## Hands-On Exercises @@ -116,16 +122,16 @@ Skills are discovered from project directories (`.github/skills/`, `.agents/skil ```yaml openapi: info: - title: API Name - version: + title: API Name + version: paths: - /resource: - get: - summary: Short description - parameters: [] - responses: - '200': - description: Success + /resource: + get: + summary: Short description + parameters: [] + responses: + '200': + description: Success ``` ### For Markdown documentation: @@ -229,15 +235,15 @@ API documentation generated following your skill's style guide. import { describe, it, expect, beforeEach } from 'jest'; import { MyService } from '../src/my-service'; - describe('MyService', => { + describe('MyService', () => { let service: MyService; - beforeEach( => { - service = new MyService; + beforeEach(() => { + service = new MyService(); }); - describe('methodName', => { - it('should return expected value for valid input', => { + describe('methodName', () => { + it('should return expected value for valid input', () => { // Arrange const input = 'valid'; @@ -248,12 +254,12 @@ API documentation generated following your skill's style guide. expect(result).toBe('expected'); }); - it('should throw error for invalid input', => { + it('should throw error for invalid input', () => { // Arrange const input = null; // Act & Assert - expect( => service.methodName(input)).toThrow('Invalid input'); + expect(() => service.methodName(input)).toThrow('Invalid input'); }); }); }); @@ -642,9 +648,15 @@ Different prompts trigger different skills, producing output that follows each s name: skill-name # Required: lowercase, hyphens, max 64 chars description: What this skill does and when to use it # Required: max 1024 chars license: MIT # Optional: License identifier +user-invocable: true # Optional: expose the skill as a slash command +aliases: [alt-name] # Optional: additional slash-command names +allowed-tools: ["bash", "view"] # Optional: restrict the tools the skill may use +disable-model-invocation: false # Optional: prevent the model from auto-selecting the skill --- ``` +Only `name` and `description` are required. The shipped built-in skills use `user-invocable: false` so they are selected by the model rather than typed as a slash command. + ### Skill Locations | Location | Scope | Priority | @@ -667,7 +679,8 @@ license: MIT # Optional: License identifier - โœ… Copilot auto-selects skills based on your request - โœ… `copilot skill add` installs skills from files, URLs, or directories - โœ… `copilot skill list --json` provides machine-readable skill inventory -- โœ… Built-in skills ship with CLI and are available without configuration +- โœ… Built-in skills `customize-cloud-agent` and `github-pr-media` ship with the CLI and need no configuration +- โœ… Frontmatter supports `user-invocable`, `aliases`, `allowed-tools`, and `disable-model-invocation` beyond `name`/`description` ## Next Steps diff --git a/docs/workshop/07-plugins.md b/docs/workshop/07-plugins.md index 93d7422..345eb04 100644 --- a/docs/workshop/07-plugins.md +++ b/docs/workshop/07-plugins.md @@ -12,6 +12,7 @@ - Explore the GitHub copilot-plugins repository - Learn about work-iq-mcp and enterprise integrations - Install and configure plugins +- Inspect plugins, MCP servers, and skills with `copilot plugins` - Understand plugin security considerations ## Concepts @@ -77,10 +78,46 @@ copilot plugin install https://github.com/owner/my-plugin.git # Inspect and maintain installed plugins copilot plugin list -copilot plugin update +copilot plugin update spark@copilot-plugins +copilot plugin update --all copilot plugin uninstall workiq ``` +`copilot plugin update` requires either a plugin name or `--all`; running it with no argument reports a missing plugin name. + +### Inspecting Resources Across Kinds + +`copilot plugins` (plural) is a separate command that inspects and manages plugins, MCP servers, skills, instruction sources, and language servers together, grouped by kind and configuration scope: + +```bash +# Everything configured for this workspace +copilot plugins list + +# Filter by kind or scope; --json for machine-readable output +copilot plugins list --kind mcp --kind skill +copilot plugins list --scope user --json + +# Install a plugin, or a skill for your user account / this project +copilot plugins install spark@copilot-plugins +copilot plugins install --skill ./my-skill/SKILL.md +copilot plugins install --skill --scope project ./my-skill/SKILL.md + +# Enable, disable, or remove by kind +copilot plugins enable github --mcp +copilot plugins disable my-skill --skill +copilot plugins remove spark@copilot-plugins + +# Browse and manage marketplaces +copilot plugins marketplace browse copilot-plugins +``` + +Supported `--kind` values are `plugin`, `mcp`, `skill`, `instruction`, and `lsp`. Supported `--scope` values are `user`, `repository`, `organization`, `plugin`, `builtin`, and `unknown`. Use `--plugin` (the default), `--mcp`, or `--skill` on `enable`, `disable`, `remove`, and `install` to disambiguate names that collide across kinds. + +> [!NOTE] +> MCP servers are installed from a policy-configured registry, which requires authentication and interactive secret entry, so `copilot plugins install --mcp` is not supported. Add them from the `/plugin` dashboard or `/mcp` instead. + +The `/plugin` slash command opens the same view as an interactive dashboard; `/plugin --plugin`, `/plugin --mcp`, and `/plugin --skill` open it on that tab, and `/plugin mcp ` delegates to `/mcp`. + ### Plugin Sources 1. **github/copilot-plugins** - Official GitHub plugins (default marketplace) @@ -96,7 +133,15 @@ copilot plugin uninstall workiq ### Plugin Hooks and Environment -Plugin hooks receive `PLUGIN_ROOT` environment variables pointing to the plugin installation directory. This allows hook scripts to reference files within the plugin package without hardcoding paths. +Hook and plugin scripts receive: + +| Variable | Points to | +|---|---| +| `PLUGIN_ROOT`, `COPILOT_PLUGIN_ROOT`, `CLAUDE_PLUGIN_ROOT` | The plugin's installation directory | +| `PLUGIN_DATA`, `COPILOT_PLUGIN_DATA`, `CLAUDE_PLUGIN_DATA` | The plugin's writable data directory | +| `COPILOT_PROJECT_DIR`, `CLAUDE_PROJECT_DIR` | The project root | + +This lets hook scripts reference files inside the plugin package, and write state, without hardcoding paths. See [Module 9: Hooks](09-hooks.md) for hook lifecycle details. ### Post-Install Messages @@ -340,23 +385,23 @@ Database query capabilities via Copilot. 'Get the current timestamp in various formats', { format: z.enum(['iso', 'unix', 'human']).default('iso') }, async ({ format }) => { - const now = new Date; + const now = new Date(); let timestamp; switch (format) { - case 'unix': timestamp = String(Math.floor(now.getTime / 1000)); break; - case 'human': timestamp = now.toLocaleString; break; - default: timestamp = now.toISOString; break; + case 'unix': timestamp = String(Math.floor(now.getTime() / 1000)); break; + case 'human': timestamp = now.toLocaleString(); break; + default: timestamp = now.toISOString(); break; } return { content: [{ type: 'text', text: timestamp }] }; } ); // Start the server over stdio - async function main { - const transport = new StdioServerTransport; + async function main() { + const transport = new StdioServerTransport(); await server.connect(transport); } - main.catch(console.error); + main().catch(console.error); EOF ``` @@ -485,16 +530,69 @@ You can evaluate and securely configure plugins. **Expected Outcome:** You can find, evaluate, and contribute to the plugin ecosystem. +### Exercise 8: Inspect Everything with `copilot plugins` + +**Goal:** Use the plural `copilot plugins` command to audit plugins, MCP servers, skills, instructions, and language servers in one place. + +**Steps:** + +1. List everything configured for the current workspace: + ```bash + copilot plugins list + ``` + Note how the output groups results by kind, then by configuration scope (user, repository, organization, plugin, built-in). + +2. Narrow the output to a single kind: + ```bash + copilot plugins list --kind mcp + copilot plugins list --kind skill + ``` + +3. Combine kind and scope filters, and take machine-readable output: + ```bash + copilot plugins list --kind mcp --kind skill --scope user --json + ``` + +4. Toggle a resource by kind. Disable the built-in GitHub MCP server, confirm it, then re-enable it: + ```bash + copilot plugins disable github --mcp + copilot plugins list --kind mcp + copilot plugins enable github --mcp + ``` + +5. Install a skill into the current project rather than your user account: + ```bash + copilot plugins install --skill --scope project ~/.copilot/skills/git-workflow/SKILL.md + ``` + > Reuse the personal `git-workflow` skill you created in Module 6. Project-scoped skills land in `.github/skills/`. + +6. Open the same view interactively: + ```bash + copilot + ``` + ``` + /plugin + /plugin --mcp + /plugin --skill + ``` + +**Expected Outcome:** +You can audit and toggle plugins, MCP servers, and skills from a single command, filter by kind and scope, and open the equivalent interactive dashboard with `/plugin`. + ## Plugin Installation Methods ### From a Marketplace -```bash -# Install from a registered marketplace in an interactive session +Install from a registered marketplace in an interactive session: + +``` /plugin install spark@copilot-plugins /plugin install some-plugin@awesome-copilot +``` + +Or install from the shell: -# Or install from the shell +```bash copilot plugin install spark@copilot-plugins copilot plugin install some-plugin@awesome-copilot ``` @@ -593,6 +691,10 @@ copilot --plugin-dir ./plugin-a --plugin-dir ./plugin-b - โœ… `copilot plugin install` installs from marketplaces, GitHub repos, repo subdirectories, or git URLs - โœ… `copilot plugin marketplace browse` discovers marketplace plugins - โœ… `copilot plugin marketplace update` refreshes plugin catalogs +- โœ… `copilot plugin update` needs a plugin name or `--all` +- โœ… `copilot plugins` (plural) inspects plugins, MCP servers, skills, instructions, and language servers by kind and scope +- โœ… `/plugin` opens the same view as an interactive dashboard +- โœ… Plugin and hook scripts get `PLUGIN_ROOT`, `PLUGIN_DATA`, and `COPILOT_PROJECT_DIR` (plus their `COPILOT_`/`CLAUDE_` variants) - โœ… Plugins can bundle skills, agents, hooks, MCP servers, and LSP servers ## Next Steps diff --git a/docs/workshop/08-custom-agents.md b/docs/workshop/08-custom-agents.md index 468ed35..472dfce 100644 --- a/docs/workshop/08-custom-agents.md +++ b/docs/workshop/08-custom-agents.md @@ -10,7 +10,7 @@ - Create custom agents with specialized personas - Configure agents at repository, organization, and enterprise levels -- Use built-in agents and workflows (Explore, Task, Plan, Code-review, Research, Fleet, Rubber-duck) +- Use built-in agents (Explore, Task, General-purpose, Code-review, Security-review, Research, Rubber-duck, REM) - Invoke agents explicitly in conversations - Build subagents for complex workflows @@ -54,8 +54,8 @@ You can create agent files manually, or use the **`/agent`** slash command in in 1. Enter `/agent` and select **Create new agent**. 2. Choose a location: - - **Project** (`.github/agents/`) - - **User** (`~/.config/copilot/agents/`) + - **Project** (`.github/agents/` or `.claude/agents/`) + - **User** (`~/.copilot/agents/`) 3. Choose whether to have Copilot generate the agent profile or create it yourself. 4. Configure tool access (default is all tools). 5. **Restart the CLI** to load your new custom agent. @@ -77,50 +77,35 @@ Custom agents can be invoked in four ways: ### Agent Hierarchy ``` -User agents (~/.config/copilot/agents/) +User agents (~/.copilot/agents/) โ†“ Enterprise agents (.github-private repo) โ†“ Organization agents (.github-private repo) โ†“ -Repository agents (.github/agents/) +Repository agents (.github/agents/ or .claude/agents/) โ†“ AGENTS.md (root or directory-specific) ``` -> **Note:** If you have custom agents with the same name in both user and repository locations, the one in your home directory (`~/.config/copilot/agents/`) will be used. +> **Note:** If you have custom agents with the same name in both user and repository locations, the one in your home directory (`~/.copilot/agents/`) will be used. ### Built-in Agents Copilot CLI includes specialized built-in agents: -| Agent | Purpose | -|-------|---------| -| **Explore** | Fast codebase analysis without context clutter; can use GitHub MCP tools when available | -| **Task** | Run commands with smart output handling | -| **Plan** | Create implementation plans | -| **Code-review** | High signal-to-noise code reviews | -| **Research** | Deep research across code, repositories, and web sources | -| **Fleet** | Parallel subagent orchestration for complex tasks | -| **Rubber-duck** | High-signal critique of plans, designs, and implementations | +| Agent | Purpose | How it runs | +|-------|---------|-------------| +| **Explore** | Fast codebase analysis without context clutter; has read-only access to GitHub MCP server tools | Selected automatically | +| **Task** | Run development commands (tests, builds, linters, formatters) with smart output handling | Selected automatically | +| **General-purpose** | Same capabilities as the main agent, in a separate context window | Selected automatically | +| **Code-review** | High signal-to-noise review of staged, unstaged, or branch diffs | Selected automatically, or `/review` | +| **Rubber-duck** | Constructive critique of plans, designs, implementations, and tests, on a complementary model | Selected automatically, or `/rubber-duck` | +| **Security-review** | Security-focused review of staged, unstaged, and branch diffs across 11 vulnerability categories | `/security-review` | +| **Research** | Deep research across code, repositories, and web sources | `/research` | +| **REM** | Background memory consolidation that updates the dynamic context board | Background only | -> **Note:** Built-in agents are not included in the `/agent` list. They are invoked via the main agent's task tool. - -### Critic Agent โ€” Experimental - -> The **critic agent** is an experimental built-in agent. It provides automated review and critique of agent-generated output before it is finalized. -> -> The critic agent: -> - Reviews code changes made by other agents for quality and correctness -> - Identifies potential issues, edge cases, and improvements -> - Provides feedback that can be incorporated before finalizing changes -> -> Enable experimental features to use the critic agent: -> ```text -> copilot --experimental -> ``` -> -> The critic agent's behavior and availability may change as it is experimental. +> **Note:** Built-in agents are not included in the `/agent` list. They are invoked via the main agent's task tool. Research, Security-review, and REM are not selected automatically โ€” Research and Security-review run from their slash commands, and REM runs in the background. ### Sub-Agent Depth and Concurrency Limits @@ -128,17 +113,11 @@ Copilot CLI includes specialized built-in agents: > - **Depth limit**: Prevents infinite sub-agent recursion (agent spawning agent spawning agent...) > - **Concurrency limit**: Controls how many sub-agents can run simultaneously > -> These limits prevent runaway resource consumption and ensure predictable behavior when agents delegate to other agents. The limits are configurable but have sensible defaults. - -### Configure-Copilot Sub-Agent +> These limits prevent runaway resource consumption and ensure predictable behavior when agents delegate to other agents. Configure them with the `subagents.maxDepth` and `subagents.maxConcurrency` settings, which apply to usage-based billing accounts. Use `subagents.disabledSubagents` to turn individual sub-agents off, and `/subagents` to set per-agent model, effort, and context-tier overrides. -> The built-in `configure-copilot` sub-agent can manage MCP servers, custom agents, and skills via the task tool. Ask Copilot to configure itself: +### Managing Configuration from a Session -``` -Help me set up an MCP server for my PostgreSQL database -``` - -Copilot delegates to the configure-copilot agent, which modifies configuration files on your behalf. +> Use `/agent`, `/mcp`, `/skills`, and `/plugin` to add, edit, enable, and disable custom agents, MCP servers, skills, and plugins without leaving the session. `/settings` writes user settings, and `/settings --repo` / `/settings --local` target repository settings. ## Hands-On Exercises @@ -154,7 +133,7 @@ Copilot delegates to the configure-copilot agent, which modifies configuration f ``` 2. Create a test-agent: - ```bash + ````bash cat > .github/agents/test-agent.agent.md << 'EOF' --- name: test-agent @@ -186,11 +165,11 @@ Copilot delegates to the configure-copilot agent, which modifies configuration f ### JavaScript/TypeScript (Jest) ```typescript - describe('ComponentName', => { - describe('methodName', => { - it('should [expected behavior] when [condition]', => { + describe('ComponentName', () => { + describe('methodName', () => { + it('should [expected behavior] when [condition]', () => { // Arrange - const input = setupTestData; + const input = setupTestData(); // Act const result = component.methodName(input); @@ -205,15 +184,15 @@ Copilot delegates to the configure-copilot agent, which modifies configuration f ### Python (pytest) ```python class TestComponentName: - def test_method_should_behavior_when_condition(self): - # Arrange - input_data = setup_test_data + def test_method_should_behavior_when_condition(self): + # Arrange + input_data = setup_test_data() - # Act - result = component.method_name(input_data) + # Act + result = component.method_name(input_data) - # Assert - assert result == expected + # Assert + assert result == expected ``` ## Edge Cases to Always Test @@ -235,7 +214,7 @@ Copilot delegates to the configure-copilot agent, which modifies configuration f - Never test private methods directly - Never create tests that depend on test order EOF - ``` + ```` 3. Restart the CLI to load the new agent, then test it: ```bash @@ -260,7 +239,7 @@ Agent creates comprehensive tests following your specifications. **Steps:** 1. Create the agent file: - ```bash + `````bash cat > .github/agents/docs-agent.agent.md << 'EOF' --- name: docs-agent @@ -303,7 +282,7 @@ Agent creates comprehensive tests following your specifications. ``` ### API Documentation Format - ```markdown + ````markdown ## Endpoint Name `METHOD /path` @@ -331,7 +310,7 @@ Agent creates comprehensive tests following your specifications. ### Errors | Code | Description | |------|-------------| - ``` + ```` ## Style Guide - Use active voice @@ -353,7 +332,7 @@ Agent creates comprehensive tests following your specifications. - Never leave TODOs in final docs - Never copy-paste code that hasn't been tested EOF - ``` + ````` 2. Restart the CLI, then test the agent: ```bash @@ -395,16 +374,18 @@ Agent creates well-structured documentation. - Brief summary on success - Full output on failure -3. **Use the Plan agent** for implementation planning: +3. **Use plan mode for implementation planning:** ``` - Create a plan to add user profile editing feature + /plan Add user profile editing feature ``` - The Plan agent: + Plan mode: - Analyzes dependencies - Creates step-by-step plans - Identifies potential blockers + > **Note:** Planning is a session **mode**, not a built-in agent. You can also start the CLI in it with `copilot --mode plan`. + 4. **Use the Code-review agent** for reviews: ``` Review the changes in the last 3 commits @@ -425,17 +406,29 @@ Agent creates well-structured documentation. - Searches available code, repositories, and web sources - Produces structured findings -6. **Use Fleet for parallel subagent work:** +6. **Use fleet mode for parallel subagent work:** ``` /fleet Add tests for each independent service module ``` - Fleet: + Fleet mode: - Decomposes complex work into parallel subagent tasks - Coordinates results through an orchestrator - Works best for independent, parallelizable changes -> **Note:** Built-in agents are not listed in the `/agent` menu. They are invoked automatically by the main agent when it determines their expertise is needed. + > **Note:** Fleet is a session **mode**, not a built-in agent. It orchestrates subagents rather than being one. + +7. **Use the Security-review agent** for a security pass: + ``` + /security-review + ``` + + The Security-review agent: + - Analyzes staged, unstaged, and branch diffs + - Covers 11 vulnerability categories + - Minimizes false positives + +> **Note:** Built-in agents are not listed in the `/agent` menu. Explore, Task, General-purpose, Code-review, and Rubber-duck are invoked automatically by the main agent when it determines their expertise is needed; Research and Security-review run from their slash commands. **Expected Outcome:** Each built-in agent provides specialized assistance. @@ -447,7 +440,7 @@ Each built-in agent provides specialized assistance. **Steps:** 1. Create a read-only analysis agent: - ```bash + ````bash cat > .github/agents/analyzer.agent.md << 'EOF' --- name: analyzer @@ -517,7 +510,7 @@ Each built-in agent provides specialized assistance. I analyze but NEVER modify files. My purpose is to report findings. For fixes, hand off to appropriate agents or developers. EOF - ``` + ```` 2. Notice the `tools` section excludes `write`. @@ -547,15 +540,15 @@ Agent performs analysis without modification capabilities. 1. User-level agents go in your home directory: ``` - ~/.config/copilot/agents/AGENT-NAME.agent.md + ~/.copilot/agents/AGENT-NAME.agent.md ``` User-level agents are available across all repositories and take priority over repository agents with the same name. 2. Create a user-level agent: ```bash - mkdir -p ~/.config/copilot/agents - cat > ~/.config/copilot/agents/security-reviewer.agent.md << 'EOF' + mkdir -p ~/.copilot/agents + cat > ~/.copilot/agents/security-reviewer.agent.md << 'EOF' --- name: security-reviewer description: Reviews code for security compliance with personal standards. @@ -576,18 +569,21 @@ Agent performs analysis without modification capabilities. 3. Restart the CLI. The agent is available in all your repositories. 4. Priority order (highest to lowest): - - **User agents** (`~/.config/copilot/agents/`) โ€” highest priority + - **User agents** (`~/.copilot/agents/`) โ€” highest priority - Enterprise agents (`.github-private` repo, enterprise level) - Organization agents (`.github-private` repo, org level) - - **Repository agents** (`.github/agents/`) + - **Repository agents** (`.github/agents/` or `.claude/agents/`) > **Note:** Enterprise and organization-level agents are configured by admins in a `.github-private` repository. See the [GitHub Docs](https://docs.github.com/en/copilot/how-tos/administer-copilot/manage-for-organization/prepare-for-custom-agents) for details. -> The `customAgents.defaultLocalOnly` config option allows you to default to only local custom agents, skipping remote org/enterprise agents. Set it in `~/.copilot/config.json`: +> The `customAgents.defaultLocalOnly` setting allows you to default to only local custom agents, skipping remote org/enterprise agents. Set it in `~/.copilot/settings.json`: > ```json > { "customAgents": { "defaultLocalOnly": true } } > ``` +> [!WARNING] +> Put user settings in `~/.copilot/settings.json`, or edit them with `/settings`. The `~/.copilot/config.json` file next to it is managed automatically and stores your authentication token โ€” never print, paste, or share it, especially while screen-sharing. + **Expected Outcome:** You understand how to deploy user-level agents and the priority hierarchy. @@ -598,7 +594,7 @@ You understand how to deploy user-level agents and the priority hierarchy. **Steps:** 1. Create a coordinator agent: - ```bash + ````bash cat > .github/agents/project-lead.agent.md << 'EOF' --- name: project-lead @@ -647,7 +643,7 @@ You understand how to deploy user-level agents and the priority hierarchy. - Highlight any blockers or concerns - Provide status updates EOF - ``` + ```` 2. Restart the CLI, then test delegation: ```bash @@ -692,7 +688,7 @@ Complex workflows coordinated across multiple agents. | Problem | Solution | |---------|----------| - | Agent not found | Check file location: `.github/agents/name.agent.md` | + | Agent not found | Check file location: `.github/agents/name.agent.md`, `.claude/agents/name.agent.md`, or `~/.copilot/agents/name.agent.md` | | Wrong behavior | Check YAML frontmatter syntax | | Tools not working | Verify tools list in frontmatter | | Description missing | Add description field | @@ -749,8 +745,8 @@ skills: # Optional: eagerly load named skills | Location | Scope | Example Path | |----------|-------|--------------| -| User | All repos (highest priority) | `~/.config/copilot/agents/name.agent.md` | -| Repository | Single repo | `.github/agents/name.agent.md` | +| User | All repos (highest priority) | `~/.copilot/agents/name.agent.md` | +| Repository | Single repo | `.github/agents/name.agent.md` or `.claude/agents/name.agent.md` | | Organization | All org repos | `.github-private/agents/name.agent.md` | | Enterprise | All enterprise repos | Same as org, enterprise level | @@ -765,22 +761,23 @@ skills: # Optional: eagerly load named skills ## Summary - โœ… Custom agents defined with `.agent.md` extension -- โœ… Create agents via `/agent` command or manually in `.github/agents/` +- โœ… Create agents via `/agent` command or manually in `.github/agents/` or `.claude/agents/` - โœ… Invoke agents via `/agent` slash command, explicit instruction, inference, or `--agent` flag -- โœ… User-level agents (`~/.config/copilot/agents/`) override repo-level agents -- โœ… Built-in agents and workflows (Explore, Task, Plan, Code-review, Research, Fleet) handle common tasks -- โœ… Rubber-duck provides focused critique for plans and implementations -- โœ… Explore agent can use GitHub MCP tools when available +- โœ… User-level agents (`~/.copilot/agents/`) override repo-level agents +- โœ… Built-in agents (Explore, Task, General-purpose, Code-review, Rubber-duck) handle common tasks automatically +- โœ… Research and Security-review run from `/research` and `/security-review`; REM consolidates memory in the background +- โœ… Plan and fleet are session modes, not agents +- โœ… Explore agent has read-only access to GitHub MCP server tools - โœ… Agent `model` field overrides the default AI model - โœ… Tool restrictions limit what agents can do - โœ… Organization agents provide team-wide standards - โœ… Agents can delegate to other agents for complex workflows - โœ… Restart the CLI after creating new `.agent.md` files (plugin-installed agents hot-load without restart) -- โœ… `configure-copilot` built-in sub-agent manages MCP, agents, and skills +- โœ… `/agent`, `/mcp`, `/skills`, `/plugin`, and `/settings` manage configuration from inside a session - โœ… Agent `model` field accepts display names and vendor suffixes - โœ… Agent `skills` field eagerly loads named skills -- โœ… Sub-agent depth and concurrency limits prevent runaway resource consumption -- โœ… โš ๏ธ **Experimental**: Critic agent provides automated review of agent output +- โœ… `subagents.maxDepth` and `subagents.maxConcurrency` bound sub-agent recursion and parallelism +- โœ… User settings belong in `~/.copilot/settings.json`; `~/.copilot/config.json` is managed automatically and holds credentials ## Next Steps diff --git a/docs/workshop/09-hooks.md b/docs/workshop/09-hooks.md index b963bb4..8105288 100644 --- a/docs/workshop/09-hooks.md +++ b/docs/workshop/09-hooks.md @@ -5,6 +5,10 @@ - Completed Modules 1-9 - Understanding of shell scripting (bash/PowerShell) - JSON basics +- A **trusted** working folder โ€” repository hooks only run in trusted folders + +> [!IMPORTANT] +> Answer **Yes, and remember** at the trust prompt the first time you launch Copilot in the folder you use for this module. Without folder trust, `.github/hooks/*.json` is discovered but never executed and no error is shown, so every exercise below would silently produce nothing. ## Learning Objectives @@ -30,26 +34,36 @@ User Prompt โ†’ Session Start โ†’ Pre-Tool โ†’ Tool Execution โ†’ Post-Tool โ†’ | Hook | Trigger | Use Cases | |------|---------|-----------| -| `sessionStart` | Session begins | Logging, environment setup | +| `sessionStart` | Session starts or resumes | Logging, environment setup | | `sessionEnd` | Session ends | Cleanup, metrics | | `userPromptSubmitted` | User sends prompt | Audit, filtering | +| `userPromptTransformed` | After a prompt is transformed into its model-facing form, before it enters history | Prompt rewriting, auditing | | `preToolUse` | Before tool execution | Permission control, validation | +| `preMcpToolCall` | Before an MCP tool request is sent | Adjust MCP request metadata | | `postToolUse` | After successful tool execution | Logging, verification | | `postToolUseFailure` | After tool execution fails | Error handling, retry logic | -| `errorOccurred` | Error happens | Error handling, alerts | +| `errorOccurred` | A model call fails | Error handling, alerts | | `preCompact` | Before context compaction | Pre-compaction tasks, state saving | +| `agentStop` | The agent stops at the end of a turn | Turn-level automation, notifications | | `subagentStart` | Sub-agent is spawned | Context injection, logging | +| `subagentStop` | Sub-agent completes | Collect sub-agent results | | `permissionRequest` | Tool permission requested | Programmatic approve/deny of tool permissions | | `notification` | Shell completion, permission prompts, elicitation, agent completion | External notification integration | ### Hook Locations -- **Copilot Coding Agent**: `.github/hooks/hooks.json` (on default branch) -- **Copilot CLI**: Hooks loaded from current working directory +- **Repository hooks**: any `*.json` file in `/.github/hooks/` (for example `hooks.json`) +- **Personal hooks**: any `*.json` file in `~/.copilot/hooks/` +- **Inline hooks**: the `hooks` key in settings, keyed by event name, using the same schema + +> [!IMPORTANT] +> Repository hooks run only in **trusted folders**. The first time you launch Copilot in a directory, answer **Yes, and remember** at the trust prompt (or add the path to `trustedFolders`). In an untrusted folder, `.github/hooks/*.json` is discovered but never executed, and no error is shown. Personal hooks in `~/.copilot/hooks/` run regardless of folder trust. +> +> Complete this before Exercise 1, or every repository hook in this module will silently do nothing. ### Disabling All Hooks -> Use the `disableAllHooks` flag in configuration to disable all hooks: +> Use the `disableAllHooks` setting to disable all hooks, both user-level and repo-level: ```json { @@ -59,6 +73,8 @@ User Prompt โ†’ Session Start โ†’ Pre-Tool โ†’ Tool Execution โ†’ Post-Tool โ†’ This is useful for debugging or CI environments where hooks may interfere with automation. +To suppress specific hooks rather than all of them, list their content-hash keys under `disabledHooks`. Policy-delivered hooks cannot be suppressed and ignore both settings. + ### Hook Permission Decisions Hooks support three permission decisions in `preToolUse`: @@ -99,18 +115,25 @@ Hooks support three permission decisions in `preToolUse`: > **Note:** `sessionStart` and `sessionEnd` hooks fire **once per session**, not once per prompt. They fire exactly once at session start and session end. For per-prompt logic, use the `userPromptSubmitted` hook. -### Hook Payload Fields +### Hook Payload Shapes -> Hook payloads use **PascalCase** field names alongside camelCase names for cross-platform compatibility. Fields include: -> - `hook_event_name` โ€” the event type (e.g., `"PreToolUse"`, `"SessionStart"`) -> - `session_id` โ€” the session identifier -> - ISO 8601 timestamps โ€” timestamps are formatted as ISO 8601 strings in addition to Unix milliseconds +> The payload a hook receives is determined by how you write the event key in the hooks file. The two shapes are mutually exclusive: > -> Both camelCase and PascalCase field names work; the PascalCase additions improve compatibility with VS Code and Claude Code hook configurations. +> | Event key casing | Payload fields | +> | --- | --- | +> | camelCase (`sessionStart`, `preToolUse`) | `sessionId`, `timestamp` (Unix milliseconds), `cwd`, `toolName`, `toolArgs` (JSON **string**), `initialPrompt` | +> | PascalCase (`SessionStart`, `PreToolUse`) | `hook_event_name`, `session_id`, `timestamp` (ISO 8601 string), `cwd`, `tool_name` (capitalised, e.g. `Bash`), `tool_input` (JSON **object**), `initial_prompt` | +> +> Use camelCase keys for hooks written for Copilot CLI; use PascalCase keys when reusing a hooks file authored for VS Code or Claude Code. -### Plugin Hook Environment +### Hook Script Environment -> Plugin hooks receive `PLUGIN_ROOT` environment variables pointing to the plugin's installation directory. This allows hook scripts packaged with plugins to reference sibling files reliably. +> Hook and plugin scripts receive: +> - `PLUGIN_ROOT`, `COPILOT_PLUGIN_ROOT`, `CLAUDE_PLUGIN_ROOT` โ€” the plugin's installation directory +> - `COPILOT_PLUGIN_DATA`, `CLAUDE_PLUGIN_DATA` โ€” the plugin's writable data directory +> - `COPILOT_PROJECT_DIR`, `CLAUDE_PROJECT_DIR` โ€” the project root +> +> This lets hook scripts packaged with plugins reference sibling files reliably. Individual discovered hooks can be suppressed with the `disabledHooks` setting; `disableAllHooks` turns off both repository and personal hooks. ### Notification Hook Event @@ -145,12 +168,23 @@ Hooks support three permission decisions in `preToolUse`: **Steps:** -1. Create the hooks directory: +1. Trust the folder you are working in. Start the CLI from the repository root and answer **Yes, and remember** at the trust prompt: + ```bash + copilot + ``` + ``` + /exit + ``` + + > [!IMPORTANT] + > Repository hooks in `.github/hooks/` are skipped in untrusted folders, with no error message. Do this first so the rest of the module works. + +2. Create the hooks directory: ```bash mkdir -p .github/hooks ``` -2. Create the hooks configuration file: +3. Create the hooks configuration file: ```bash cat > .github/hooks/hooks.json << 'EOF' { @@ -166,10 +200,12 @@ Hooks support three permission decisions in `preToolUse`: EOF ``` -3. This is the skeleton - we'll add hooks in subsequent exercises. + > **Note:** The file name is up to you โ€” every `*.json` file in `.github/hooks/` is loaded. `hooks.json` is just a convention. + +4. This is the skeleton - we'll add hooks in subsequent exercises. **Expected Outcome:** -Hooks configuration file ready for customization. +Hooks configuration file ready for customization, in a trusted folder so hooks will actually run. ### Exercise 2: Session Logging Hooks @@ -765,6 +801,29 @@ All tool executions are logged with results: > **Note:** `resultType` is `"success"` or `"error"`. `toolArgs` is a JSON string. +#### userPromptTransformed +```json +{ + "sessionId": "uuid-string", + "timestamp": 1771976925250, + "cwd": "/path/to/workspace", + "prompt": "User's prompt text", + "transformedPrompt": "The model-facing form of the prompt" +} +``` + +#### agentStop +```json +{ + "sessionId": "uuid-string", + "timestamp": 1771976928900, + "cwd": "/path/to/workspace", + "transcriptPath": "/home/you/.copilot/session-state/uuid-string/events.jsonl", + "stopReason": "end_turn", + "stop_hook_active": false +} +``` + ### Permission Decision Response ```json @@ -789,23 +848,28 @@ All tool executions are logged with results: ## Summary - โœ… Hooks execute at key points in agent lifecycle +- โœ… Repository hooks only run in **trusted folders** โ€” untrusted folders skip them silently +- โœ… Repository hooks live in any `*.json` file under `/.github/hooks/`; personal hooks under `~/.copilot/hooks/` - โœ… `preToolUse` enables security guardrails - โœ… `postToolUse` allows verification and logging (fires only on successful tool calls) - โœ… `postToolUseFailure` handles tool errors separately - โœ… `permissionRequest` hook enables programmatic approve/deny of tool permissions - โœ… Session hooks enable auditing -- โœ… Error hooks support monitoring integration +- โœ… `errorOccurred` fires when a model call fails - โœ… Hooks must return JSON for permission decisions - โœ… `preCompact` hook fires before context compaction -- โœ… `subagentStart` hook fires when a sub-agent is spawned -- โœ… `disableAllHooks` flag disables all hooks +- โœ… `userPromptTransformed` fires after a prompt is turned into its model-facing form +- โœ… `preMcpToolCall` fires before an MCP tool request is sent +- โœ… `agentStop` fires when the agent stops at the end of a turn +- โœ… `subagentStart` and `subagentStop` fire when a sub-agent is spawned and when it completes +- โœ… `disableAllHooks` disables every hook; `disabledHooks` suppresses individual ones (policy hooks ignore both) - โœ… Hook `ask` permission decision prompts user for confirmation - โœ… Cross-platform hook configs work across VS Code, Claude Code, and CLI -- โœ… Hooks can also be defined in `settings.json`, `settings.local.json`, and `config.json` +- โœ… Hooks can also be declared inline under the `hooks` key in settings - โœ… `preToolUse` hooks respect `modifiedArgs`/`updatedInput`/`additionalContext` - โœ… `sessionStart`/`sessionEnd` hooks fire once per session, not per prompt -- โœ… Hook payloads include PascalCase fields, `hook_event_name`, `session_id`, ISO 8601 timestamps -- โœ… Plugin hooks receive `PLUGIN_ROOT` env vars +- โœ… camelCase event keys yield camelCase payloads; PascalCase event keys yield `hook_event_name`/`session_id`/ISO 8601 payloads +- โœ… Hook and plugin scripts receive `PLUGIN_ROOT`, `COPILOT_PLUGIN_DATA`, and `COPILOT_PROJECT_DIR` env vars - โœ… `notification` hook event fires on shell completion, permission prompts, elicitation, agent completion ## Next Steps @@ -815,4 +879,6 @@ All tool executions are logged with results: ## References - [Hooks Configuration - GitHub Docs](https://docs.github.com/en/copilot/reference/hooks-configuration) +- [About Hooks - GitHub Docs](https://docs.github.com/en/copilot/concepts/agents/hooks) +- [Using Hooks with Copilot CLI - GitHub Docs](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/use-hooks) - [Use Hooks - GitHub Docs](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/use-hooks) diff --git a/docs/workshop/10-context.md b/docs/workshop/10-context.md index d734a52..03634a2 100644 --- a/docs/workshop/10-context.md +++ b/docs/workshop/10-context.md @@ -44,18 +44,20 @@ Context is everything Copilot "remembers" during a session: ### Context Window Tier -You can select a context window tier for tiered-pricing models using the `--context` flag or the `contextTier` config option: +You can select a context window tier for tiered-pricing models using the `--context` flag or the `contextTier` setting: ```bash # Use long context mode for a session copilot --context long_context -# Or set in config.json -# "contextTier": "long_context" +# Or set "contextTier": "long_context" in ~/.copilot/settings.json ``` Available tiers: `"default"` and `"long_context"`. The `/model` command shows a context tier picker for eligible models. +> [!WARNING] +> User settings belong in `~/.copilot/settings.json` โ€” you can also edit them with `/settings`. The `~/.copilot/config.json` file next to it is managed automatically and stores your authentication token. Never print, paste, or share its contents, especially while screen-sharing. + ### Including Files with `@` You can include a specific file's contents in your prompt using `@` followed by the relative path: @@ -526,7 +528,7 @@ Systematic workflow keeps context under control. - โœ… Efficient prompting extends useful session length - โœ… Explore agent preserves main context - โœ… `@` file mentions support absolute, home, and parent paths -- โœ… `--context` flag and `contextTier` config select context window tier for eligible models +- โœ… `--context` flag and the `contextTier` setting in `~/.copilot/settings.json` select the context window tier for eligible models - โœ… Reasoning token usage shown in per-model breakdown via `/usage` ## Next Steps diff --git a/docs/workshop/11-sessions.md b/docs/workshop/11-sessions.md index b639fd2..034fb14 100644 --- a/docs/workshop/11-sessions.md +++ b/docs/workshop/11-sessions.md @@ -34,6 +34,15 @@ Sessions are stored in your Copilot config directory: - Default: `~/.copilot/` - Custom: Set via `COPILOT_HOME` environment variable +Within that directory, session data lives in two places: + +| Path | Contents | +| --- | --- | +| `~/.copilot/session-state//` | Per-session transcript (`events.jsonl`), checkpoints, rewind snapshots, and workspace metadata | +| `~/.copilot/session-store.db` | Index of all sessions used by `/session`, `/resume`, and `--resume` | + +Manage this data with the `/session` subcommands rather than by deleting files by hand. + ## Hands-On Exercises ### Exercise 1: Session Persistence @@ -377,8 +386,25 @@ Session transcript saved for future reference or sharing. | `/share` | Export session transcript (interactive alternative to `--share` flag) | `/share` | | `/share html` | Export session as self-contained interactive HTML file; shows `file://` URL and `Ctrl+X O` to open | `/share html` | | `/model` | Switch AI model | `/model` | -| `/undo` | Undo the last turn when possible | `/undo` | -| `/rewind` | Roll back to any point in conversation history (also via double-Esc) | `/rewind` | +| `/rewind` (alias `/undo`) | Rewind the last turn and revert file changes; also available via double-Esc | `/rewind` | + +### `/session` Subcommands + +`/session` on its own opens the session manager. Add a subcommand to go straight to a specific view or action: + +| Subcommand | Description | +| --- | --- | +| `/session` | Open the session picker | +| `/session ` | Switch to a session by ID | +| `/session info` | Show details about the current session | +| `/session checkpoints [n]` | List checkpoints for the current session | +| `/session files` | List files touched in the current session | +| `/session plan` | Show the current session's plan | +| `/session rename [name]` | Rename the current session, or auto-generate a name | +| `/session cleanup` | Remove stale session records | +| `/session prune` | Prune old session data | +| `/session delete [id]` | Delete a session | +| `/session delete-all` | Delete all sessions | ## Command Line Flags @@ -390,18 +416,18 @@ Session transcript saved for future reference or sharing. | `--connect[=sessionId]` | Connect directly to a remote session (optionally specify session ID or task ID) | | `--share PATH` | Export to markdown file | | `--share-gist` | Export to GitHub Gist | -| `--silent` | Suppress stats/logs | +| `--silent` | Output only agent response (no stats) | ## Summary - โœ… Sessions maintain conversation history and context - โœ… Use `--resume` to continue previous sessions - โœ… `/clear` abandons the session; `/new` starts fresh while keeping the old session backgrounded -- โœ… `/undo` undoes the last turn when possible -- โœ… `/rewind` (or double-Esc) opens a timeline picker for rolling back to any conversation point +- โœ… `/rewind` (alias `/undo`, or double-Esc) rewinds the last turn and reverts file changes - โœ… `/rename` auto-generates a session name from conversation history when called without arguments - โœ… `--name` flag sets a session name at launch; `--resume` accepts a session name for lookup - โœ… `/cwd` and `/add-dir` control file access scope; `/cwd` sets the working directory per session +- โœ… `/session` subcommands inspect and prune session data (`info`, `checkpoints`, `files`, `prune`, `delete-all`) - โœ… Run multiple sessions in different terminals - โœ… Export sessions with `--share` for documentation or `/share html` for interactive HTML - โœ… `/share html` shows `file://` URL and `Ctrl+X O` shortcut to open in browser diff --git a/docs/workshop/12-advanced.md b/docs/workshop/12-advanced.md index 29264f0..63f2d82 100644 --- a/docs/workshop/12-advanced.md +++ b/docs/workshop/12-advanced.md @@ -33,12 +33,17 @@ Session Overrides (flags) | Directory | Purpose | | --------- | --------- | | `~/.copilot/` | Default config location | -| `~/.copilot/config.json` | User settings | +| `~/.copilot/settings.json` | User settings | +| `~/.copilot/config.json` | Machine-managed state and credentials (do not edit) | | `~/.copilot/mcp-config.json` | MCP servers | +| `~/.copilot/lsp-config.json` | Language servers | | `~/.copilot/skills/` | Personal skills | | `~/.agents/skills/` | Personal skill discovery directory (shared with VS Code extension) | | `.github/` | Repository config | +> [!WARNING] +> `~/.copilot/config.json` is managed automatically and stores your authentication token. Do not print, copy, or share it โ€” especially while screen sharing. Put user settings in `~/.copilot/settings.json`, or use `/settings` to edit them. + ### Commands & Features The following commands and features are available: @@ -61,7 +66,7 @@ The `/pr` command can also automatically fix CI failures, address review feedbac The `write_agent` tool enables multi-turn conversations with background agents โ€” send follow-up messages to agents spawned via the task tool. -Sub-agents launched by the task tool are assigned **human-readable IDs** based on their name (e.g., `math-helper-0`) instead of generic `agent-0` identifiers. +Sub-agents launched by the task tool are assigned **human-readable IDs** based on their name (e.g., `math-helper-0`). The `read_agent` output includes inbound messages that triggered each turn in multi-turn agents. @@ -101,7 +106,7 @@ Use the `--remote` flag or `/remote` command to start a remote control session: #### `copilot help monitoring` -> The new `copilot help monitoring` topic documents how to configure OpenTelemetry for observability: +> The `copilot help monitoring` topic documents how to configure OpenTelemetry for observability: > > ```text > copilot help monitoring @@ -109,12 +114,12 @@ Use the `--remote` flag or `/remote` command to start a remote control session: > > This covers OTLP exporter configuration, span attributes, and integration with monitoring backends. -#### OpenTelemetry Monitoring Enhancements +#### OpenTelemetry Monitoring -> OpenTelemetry monitoring has been expanded: +> OpenTelemetry monitoring covers: > - Sub-agent spans are tagged as `INTERNAL` spans for better trace visualization > - `time_to_first_chunk` metric tracks latency from request to first streaming chunk -> - Improved span attributes for debugging agent behavior and performance +> - Span attributes for debugging agent behavior and performance #### Custom Model Providers (BYOK) @@ -143,13 +148,33 @@ Use the `--remote` flag or `/remote` command to start a remote control session: > > | Topic | Content | > |-------|---------| +> | `billing` | AI credit usage | > | `commands` | Interactive mode commands | > | `config` | Configuration settings | > | `environment` | Environment variables | +> | `limits` | Session limits controls | > | `logging` | Logging configuration | > | `monitoring` | OpenTelemetry monitoring | > | `permissions` | Tool, URL, and path permissions | > | `providers` | Custom model providers (BYOK) | +> | `sandbox` | Command sandboxing | + +#### Session Limits & AI Credits + +> Session limits are opt-in and cap AI credit consumption for a session. Usage accumulates across the whole conversation, and subagents share the parent session's limit. +> +> ```bash +> # Cap a session at the minimum allowed AI credit limit +> copilot --max-ai-credits 30 +> ``` +> +> | Command | Description | +> | --- | --- | +> | `/limits` | Open the interactive limits dialog for the current session | +> | `/limits set max-ai-credits ` | Set the AI credit limit (minimum 30) | +> | `/limits unset [max-ai-credits]` | Remove a configured limit | +> +> The AI credit limit is a **soft cap**: usage is only known after a model response returns, so a single call can exceed the limit before the CLI blocks the next one. `/clear` and `/new` reset used credits but keep the configured limit. Run `copilot help limits` and `copilot help billing` for the full reference. ## Hands-On Exercises @@ -212,27 +237,27 @@ Environment variables customize Copilot behavior. name: Copilot Code Review on: - pull_request: - types: [opened, synchronize] + pull_request: + types: [opened, synchronize] jobs: - review: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - run: git checkout "$GITHUB_SHA" - - - name: Install Copilot CLI - run: npm install -g @github/copilot - - - name: Run Code Review - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT }} - run: | - copilot -p "Review the changes in this PR and provide feedback" \ - --allow-tool 'shell(git)' \ - --deny-tool 'write' \ - --silent + review: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + run: git checkout "$GITHUB_SHA" + + - name: Install Copilot CLI + run: npm install -g @github/copilot + + - name: Run Code Review + env: + COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT }} + run: | + copilot -p "Review the changes in this PR and provide feedback" \ + --allow-tool 'shell(git)' \ + --deny-tool 'write' \ + --silent ``` 2. **Pre-commit hook:** @@ -491,6 +516,9 @@ Copilot autonomously completes multi-step tasks with minimal human intervention. ```bash copilot + ``` + + ``` /fleet "Refactor all components in src/components/ to use TypeScript and add unit tests" ``` @@ -527,7 +555,7 @@ Copilot autonomously completes multi-step tasks with minimal human intervention. 6. **Parallel dispatch optimization:** - ```bash + ``` # Fleet automatically maximizes parallelism /fleet "Generate API routes, database models, and tests for User, Product, Order entities" @@ -557,6 +585,9 @@ Copilot autonomously completes multi-step tasks with minimal human intervention. ```bash copilot --allow-tool 'write' --allow-tool 'shell(npm test)' + ``` + + ``` /fleet "Create and test all CRUD endpoints for the API" ``` @@ -625,9 +656,9 @@ Complex tasks are completed faster through parallel sub-agent execution with qua # Copilot's shell commands will have access to DB_HOST, DB_PORT, etc. ``` -4. **Shell mode access change:** +4. **Shell mode access:** - > **Important**: shell mode is no longer accessible via Shift+Tab cycling. + > **Important**: Shift+Tab cycles chat โ†’ plan โ†’ autopilot. Shell mode is entered with `!`. **Shell mode is not part of the Shift+Tab cycle.** Instead: @@ -668,176 +699,188 @@ Complex tasks are completed faster through parallel sub-agent execution with qua ``` **Expected Outcome:** -Shell sessions have consistent environment configuration, and you understand the new shell mode access pattern. +Shell sessions have consistent environment configuration, and you understand how to enter shell mode. ### Exercise 7: LSP and Language Server Configuration -**Goal:** Configure Language Server Protocol (LSP) timeout settings. +**Goal:** Configure Language Server Protocol (LSP) servers so Copilot CLI gets real code intelligence for your languages. **Steps:** -1. **What is LSP timeout configuration?** +1. **Understand what LSP adds:** - Copilot CLI can use language servers (TypeScript, Python, Go, etc.) for: - - Code intelligence and completions + Copilot CLI can talk to language servers (TypeScript, Python, Ruby, Go, and others) for: + - Code intelligence and symbol lookup - Jump to definition - Find references - - Type information + - Type information and diagnostics - Some language servers may timeout on large codebases. The `lsp.json` config lets you adjust these timeouts. + Language servers must be configured explicitly โ€” none are enabled by default. Install the language server binary first, then point Copilot CLI at it. -2. **Create lsp.json configuration:** +2. **Install a language server:** ```bash - # Create LSP config in Copilot config directory - cat > ~/.copilot/lsp.json << 'EOF' + # TypeScript / JavaScript + npm install -g typescript typescript-language-server + + # Python + npm install -g pyright + + # Ruby + gem install ruby-lsp + ``` + +3. **Create the LSP configuration:** + + Copilot CLI reads two files, both using the same schema: + + | File | Scope | + | --- | --- | + | `~/.copilot/lsp-config.json` | Personal โ€” applies to all your projects | + | `.github/lsp.json` | Project โ€” checked in, applies to everyone on the repo | + + ```bash + cat > ~/.copilot/lsp-config.json << 'EOF' { - "timeout": { - "initialization": 30000, - "request": 10000, - "shutdown": 5000 - }, - "servers": { - "typescript": { - "timeout": { - "initialization": 60000, - "request": 20000 - } - }, - "python": { - "timeout": { - "initialization": 45000, - "request": 15000 - } - } - } + "lspServers": { + "typescript": { + "command": "typescript-language-server", + "args": ["--stdio"], + "fileExtensions": { + ".ts": "typescript", + ".tsx": "typescriptreact", + ".js": "javascript", + ".jsx": "javascriptreact" + } + }, + "python": { + "command": "pyright-langserver", + "args": ["--stdio"], + "fileExtensions": { + ".py": "python", + ".pyi": "python" + } + } + } } EOF ``` -3. **Timeout values explained:** - - `initialization`: Time allowed for LSP server to start (milliseconds) - - `request`: Time allowed for individual LSP requests - - `shutdown`: Time allowed for graceful shutdown + Each server name must be unique and contain only alphanumeric characters, underscores, and hyphens. - **Default values (if not configured):** - - initialization: 15000ms (15 seconds) - - request: 90000ms (90 seconds) โ€” increased from 30s - - shutdown: 3000ms (3 seconds) +4. **Server definition fields:** -4. **When to adjust LSP timeouts:** + | Field | Required | Description | + | --- | --- | --- | + | `command` | Yes | Executable that starts the language server. Use `bash` or `powershell` instead to launch it through a script | + | `args` | No | Arguments passed to the command | + | `fileExtensions` | Yes | Map of file extension to language ID, e.g. `{ ".rs": "rust" }` | + | `env` | No | Environment variables for the server process; supports `${VAR}` and `${VAR:-default}` expansion | + | `cwd` | No | Working directory for the server process | + | `rootUri` | No | Project root relative to the git root; defaults to `"."`. Useful in monorepos | + | `initializationOptions` | No | Custom options sent to the server during startup | + | `requestTimeoutMs` | No | Timeout for individual server requests (default: 90 seconds) | + | `initializationTimeoutMs` | No | Timeout for the server's initialize handshake | + | `spawnTimeoutMs` | No | Timeout for spawning the server process | + | `warmupTimeoutMs` | No | Timeout for the server's initial project load | + | `disabled` | No | Set to `true` to keep the definition but stop starting the server | - ```bash - # Increase if you see errors like: - # "TypeScript language server initialization timeout" - # "LSP request timeout for workspace/symbol" +5. **Tune timeouts for large repositories:** - # Common scenarios: - # - Large monorepos with thousands of files - # - Slow file systems (network drives, container volumes) - # - Resource-constrained environments - # - Complex TypeScript projects with heavy type inference + ```json + { + "lspServers": { + "typescript": { + "command": "typescript-language-server", + "args": ["--stdio"], + "fileExtensions": { ".ts": "typescript", ".tsx": "typescriptreact" }, + "requestTimeoutMs": 120000, + "initializationTimeoutMs": 90000, + "warmupTimeoutMs": 60000 + } + } + } ``` -5. **Per-language server configuration:** + Raise these when you see language server startup or request timeouts on: + - Large monorepos with thousands of files + - Slow file systems (network drives, container volumes) + - Resource-constrained environments + - Complex TypeScript projects with heavy type inference + +6. **Disable a server without removing it:** ```json { - "servers": { - "typescript": { - "timeout": { - "initialization": 90000, - "request": 30000 - }, - "maxNumberOfProblems": 100 - }, - "rust": { - "timeout": { - "initialization": 120000, - "request": 45000 - } - } - } + "lspServers": { + "python": { + "command": "pyright-langserver", + "args": ["--stdio"], + "fileExtensions": { ".py": "python" }, + "disabled": true + } + } } ``` -6. **Verify LSP configuration:** +7. **Manage servers from a session:** + + | Subcommand | Description | + | --- | --- | + | `/lsp show` | Display configured language servers and their configuration | + | `/lsp logs` | Open the live LSP services panel (status + server logs) | + | `/lsp test ` | Test whether a language server starts correctly | + | `/lsp reload` | Reload LSP configurations from disk | ```bash - # Check if config is valid JSON - cat ~/.copilot/lsp.json | jq . + # Validate the file is well-formed JSON + cat ~/.copilot/lsp-config.json | jq . - # Start Copilot and check for LSP initialization copilot - # Watch for language server startup messages in debug mode ``` -7. **Debug LSP issues:** + ``` + /lsp show + /lsp test typescript + ``` - ```bash - # Enable debug logging - export COPILOT_DEBUG=1 - copilot + `/lsp show` prints the resolved user config path along with each configured server and its file extensions. - # Look for LSP-related messages: - # "Initializing TypeScript language server..." - # "LSP initialization complete in 23457ms" - # "LSP request: textDocument/definition" - ``` +8. **Troubleshoot startup problems:** -8. **Disable LSP for specific languages:** + ```bash + # Capture detailed logs while the servers start + copilot --log-level all --log-dir ./lsp-logs - ```json - { - "servers": { - "javascript": { - "enabled": false - } - } - } + # Then inspect the log directory + ls ./lsp-logs/ ``` **Expected Outcome:** -Language server timeouts are configured for your environment, eliminating timeout errors in large projects. +Language servers are configured and verified with `/lsp test`, and you can tune per-server timeouts for large projects. ### Exercise 8: Configuration File Deep Dive -**Goal:** Understand and customize config.json and related configuration files. +**Goal:** Understand and customize `settings.json` and the related configuration files. + +> [!WARNING] +> `~/.copilot/config.json` is managed automatically by the CLI and holds your authentication token and trusted-folder state. Never print, copy, or share it โ€” especially while screen sharing. Your own preferences belong in `~/.copilot/settings.json`. **Steps:** -1. View current configuration: +1. View your current user settings: ```bash - cat ~/.copilot/config.json + cat ~/.copilot/settings.json | jq . ``` -2. Example full configuration: +2. Example settings file: ```json { - "trustedFolders": [ - "/home/user/projects", - "/home/user/work" - ], "model": "auto", - "theme": "dark", - "autoUpdate": true - } - ``` - -3. Add trusted folders: - - ```bash - # Using jq to update config - jq '.trustedFolders += ["/new/path"]' ~/.copilot/config.json > tmp.json - mv tmp.json ~/.copilot/config.json - ``` - -4. Configure URL restrictions: - - ```json - { + "theme": "github", + "autoUpdate": true, "allowedUrls": [ "https://api.github.com/*", "https://docs.github.com/*" @@ -848,8 +891,29 @@ Language server timeouts are configured for your environment, eliminating timeou } ``` +3. Change a setting from inside a session instead of editing the file by hand: + + ```bash + copilot + ``` + + ``` + /settings theme dim + /settings show theme + ``` + + `/settings` writes to `settings.json`. Run `/settings` with no arguments to open the settings dialog, and `/settings unset ` to remove a key. + +4. Grant a folder read/execute permission: + + Trusted folders are recorded in the machine-managed `config.json` when you approve a folder at startup. Approve the prompt when Copilot CLI asks about a new directory, or widen access for a session with `--add-dir`: + + ```bash + copilot --add-dir /new/path + ``` + **Expected Outcome:** -Custom configuration for your workflow, including LSP settings from Exercise 7. +Custom user settings for your workflow in `settings.json`, plus the LSP configuration from Exercise 7 โ€” with credentials left untouched. ### Exercise 9: Troubleshooting Guide @@ -861,11 +925,16 @@ Custom configuration for your workflow, including LSP settings from Exercise 7. ```bash # Clear credentials and re-authenticate - rm -rf ~/.copilot/auth* copilot - # Follow OAuth flow ``` + ``` + /logout + /login + ``` + + Credentials are held in your system credential store, or in the machine-managed `~/.copilot/config.json` when no credential store is available. Use `/logout` rather than deleting files. + 2. **Tool not working:** ```bash @@ -874,17 +943,30 @@ Custom configuration for your workflow, including LSP settings from Exercise 7. # Verify MCP servers copilot + ``` + + ``` /mcp ``` 3. **Session issues:** ```bash - # Clear session data - rm -rf ~/.copilot/sessions/ + # Inspect session data + ls ~/.copilot/session-state/ - # Start fresh + # Prune from inside a session instead of deleting files copilot + ``` + + ``` + /session prune + /session delete-all + ``` + + Or start fresh in the current session: + + ``` /clear ``` @@ -893,12 +975,16 @@ Custom configuration for your workflow, including LSP settings from Exercise 7. ```bash # Check context usage copilot + ``` + + ``` /context + ``` - # Compact if needed - /compact + Compact if needed, or start fresh: - # Or start fresh + ``` + /compact /clear ``` @@ -930,6 +1016,9 @@ Custom configuration for your workflow, including LSP settings from Exercise 7. ```bash copilot + ``` + + ``` /diagnose ``` @@ -946,20 +1035,20 @@ You can diagnose and resolve common problems using `/diagnose`, LSP timeout tuni 1. **Standardize repository configuration:** - ```bash + ```text # Create a template repository with: .github/ - โ”œโ”€โ”€ copilot-instructions.md # Team coding standards + โ”œโ”€โ”€ copilot-instructions.md # Team coding standards โ”œโ”€โ”€ agents/ - โ”‚ โ”œโ”€โ”€ reviewer.md # Code review agent - โ”‚ โ””โ”€โ”€ docs.md # Documentation agent + โ”‚ โ”œโ”€โ”€ reviewer.agent.md # Code review agent + โ”‚ โ””โ”€โ”€ docs.agent.md # Documentation agent โ”œโ”€โ”€ instructions/ - โ”‚ โ”œโ”€โ”€ typescript.instructions.md - โ”‚ โ””โ”€โ”€ tests.instructions.md + โ”‚ โ”œโ”€โ”€ typescript.instructions.md + โ”‚ โ””โ”€โ”€ tests.instructions.md โ””โ”€โ”€ hooks/ - โ””โ”€โ”€ hooks.json # Security guardrails + โ””โ”€โ”€ hooks.json # Security guardrails - AGENTS.md # Project-specific agent + AGENTS.md # Project-specific agent ``` 2. **Create onboarding documentation:** @@ -1077,11 +1166,14 @@ Team-wide standardization on Copilot usage, including shared LSP and environment ```bash # Faster than sequential processing copilot - /fleet "Update all 50 components to the API format" + ``` - # Multiple agents work in parallel + ``` + /fleet "Update all 50 components to the API format" ``` + Multiple agents work in parallel. + 7. **Parallel sessions for independent tasks:** ```bash @@ -1110,6 +1202,9 @@ Maximum performance from Copilot CLI using parallelization, autopilot, and fleet ```bash copilot + ``` + + ``` /research "Compare the trade-offs of REST vs GraphQL for mobile backends" ``` @@ -1121,7 +1216,7 @@ Maximum performance from Copilot CLI using parallelization, autopilot, and fleet 2. **Export research output:** - ```bash + ``` # After /research completes, export the report /share ./research-report.md ``` @@ -1130,11 +1225,14 @@ Maximum performance from Copilot CLI using parallelization, autopilot, and fleet ```bash copilot --allow-tool 'web_fetch' --deny-tool 'write' - /research "What are current best practices for Node.js error handling?" + ``` - # Read-only research โ€” Copilot can fetch web content but won't modify files + ``` + /research "What are current best practices for Node.js error handling?" ``` + Read-only research โ€” Copilot can fetch web content but won't modify files. + 4. **Session insights with `/chronicle`:** > `/chronicle` is experimental. Subcommands and behavior may change. @@ -1143,21 +1241,32 @@ Maximum performance from Copilot CLI using parallelization, autopilot, and fleet ```bash copilot + ``` - # Generate a standup summary from recent sessions + ``` + # Generate a standup report from your recent work /chronicle standup + # Search all session content by keyword or topic + /chronicle search + # Get tips based on your usage patterns /chronicle tips - # Get suggestions to improve your workflow + # Get suggestions for reducing token usage and cost + /chronicle cost-tips + + # Get suggestions for improving copilot-instructions.md /chronicle improve ``` `/chronicle` subcommands: - - **`standup`** โ€” Summarizes what you accomplished across recent sessions (useful for daily standups) - - **`tips`** โ€” Suggests Copilot features you may not be using effectively - - **`improve`** โ€” Analyzes patterns and recommends workflow improvements + - **`standup`** โ€” Report on your work from the last day + - **`search`** โ€” Search all session content by keyword or topic + - **`tips`** โ€” Personalized tips based on your usage patterns + - **`cost-tips`** โ€” Personalized tips to reduce token usage and cost + - **`improve`** โ€” Suggest improvements to `copilot-instructions.md` + - **`reindex`** โ€” Reload data into the session store index **Expected Outcome:** You can run deep-research workflows and extract insights from your session history. @@ -1170,9 +1279,11 @@ You can run deep-research workflows and extract insights from your session histo | File | Purpose | | ------ | --------- | -| `~/.copilot/config.json` | User settings | +| `~/.copilot/settings.json` | User settings | +| `~/.copilot/config.json` | Managed state and credentials (do not edit) | | `~/.copilot/mcp-config.json` | MCP servers | -| `~/.copilot/lsp.json` | LSP timeout configuration | +| `~/.copilot/lsp-config.json` | Language server definitions | +| `.github/lsp.json` | Project language server definitions | | `~/.copilot/skills/` | Personal skills | | `~/.agents/skills/` | Personal skill discovery (shared with VS Code) | | `.github/copilot-instructions.md` | Repository instructions | @@ -1189,7 +1300,7 @@ You can run deep-research workflows and extract insights from your session histo | `--yolo` / `--allow-all` | Allow all tools, paths, and URLs | | `--allow-tool` / `--deny-tool` | Allow/deny specific tools | | `--allow-url` / `--deny-url` | Allow/deny specific URLs | -| `--silent` | Suppress output | +| `--silent` | Output only agent response (no stats) | | `--output-format` | Output as `text` or `json` (JSONL) | | `--share PATH` | Export to markdown | | `--share-gist` | Export to Gist | @@ -1209,7 +1320,8 @@ You can run deep-research workflows and extract insights from your session histo | `--stream` | Enable/disable streaming (on/off) | | `--bash-env` | Source BASH_ENV in shell sessions | | `--experimental` | Enable experimental features | -| `--mouse` / `--no-mouse` | Mouse behavior | +| `--mouse [on\|off]` | Enable or disable mouse support in alt screen mode | +| `--no-mouse` | Disable mouse support in alt screen mode | | `--effort` | Shorthand for `--reasoning-effort` | | `--secret-env-vars` | Redact env var values | | `--no-custom-instructions` | Disable AGENTS.md loading | @@ -1234,14 +1346,16 @@ You can run deep-research workflows and extract insights from your session histo | `/after` | Schedule a one-shot prompt or skill | | `/every` | Schedule a recurring prompt or skill | | `/limits` | View or edit session limits | +| `/lsp` | Manage language server configuration | +| `/sandbox` | Show or configure command sandboxing (experimental) | +| `/settings` | Open the settings UI, or show, set, and unset individual settings | | `/statusline` | Configure status line items | | `/subagents` | Configure default and per-agent subagent models | | `Shift+Tab` | Cycle through chat / plan / autopilot modes | | `/research` | Launch deep-research workflow with exportable reports | -| `/chronicle` | Session-history insights (standup, tips, improve) โ€” experimental | +| `/chronicle` | Session-history insights (standup, search, tips, cost-tips, improve, reindex) โ€” experimental | | `/diagnose` | Show diagnostic summary of session and environment | -| `/undo` | Undo the last turn when possible | -| `/rewind` | Timeline picker to roll back to any point (also double-Esc) | +| `/rewind` (alias `/undo`) | Rewind the last turn and revert file changes; also via double-Esc | | `/copy` | Copy last response to clipboard | | `/ide` | Connect to IDE workspace | | `/mcp` | Manage MCP servers | @@ -1288,11 +1402,11 @@ alias cop-resume='copilot --resume' - โœ… **Configurable status line** displays dynamic session info via custom shell scripts - โœ… **Environment loading indicator** shows skills, MCPs, and plugins being loaded at startup - โœ… **Status line responsive layout** auto-switches to two-line layout on narrow terminals -- โœ… **Expanded `--help` output** with descriptions, examples, and sorted flags +- โœ… **`--help` output** includes descriptions, examples, and sorted flags - โœ… **`/research` command** for deep-research workflows with exportable reports - โœ… **Parallel tool execution** is always enabled -- โœ… **`/chronicle` command** (experimental) for session-history insights: standup, tips, improve -- โœ… **`--mouse`/`--no-mouse` flag** controls mouse behavior +- โœ… **`/chronicle` command** (experimental) for session-history insights: standup, search, tips, cost-tips, improve, reindex +- โœ… **`--mouse [on|off]` and `--no-mouse` flags** control mouse support in alt screen mode - โœ… **`--effort` flag** shorthand for `--reasoning-effort` - โœ… **Monorepo support** discovers instructions, MCPs, skills, and agents from cwd to git root - โœ… **`/diagnose` command** for troubleshooting session and environment issues @@ -1305,10 +1419,13 @@ alias cop-resume='copilot --resume' - โœ… **Remote control sessions** via `--remote` or `/remote` - โœ… **ACP clients** can provide MCP servers when starting/loading sessions - โœ… **`copilot help monitoring`** documents OpenTelemetry configuration -- โœ… **OpenTelemetry enhancements** โ€” sub-agent INTERNAL spans, `time_to_first_chunk` metric -- โœ… **LSP configuration** controls language server timeouts; default request timeout is 90s +- โœ… **`copilot help `** covers billing, commands, config, environment, limits, logging, monitoring, permissions, providers, and sandbox +- โœ… **OpenTelemetry monitoring** โ€” sub-agent INTERNAL spans, `time_to_first_chunk` metric +- โœ… **Session limits** are opt-in via `--max-ai-credits` and `/limits` (soft cap, minimum 30 AI credits) +- โœ… **LSP configuration** defines language servers explicitly in `~/.copilot/lsp-config.json` or `.github/lsp.json`; none run by default - โœ… **Shell mode access** via `!` command -- โœ… config.json and lsp.json persist preferences +- โœ… `settings.json` holds user preferences; `lsp-config.json` defines language servers +- โœ… `config.json` is machine-managed and holds credentials โ€” never print or share it - โœ… Team standardization ensures consistency - โœ… Performance optimization maximizes productivity diff --git a/docs/workshop/13-configuration.md b/docs/workshop/13-configuration.md index 456b5b0..eca003f 100644 --- a/docs/workshop/13-configuration.md +++ b/docs/workshop/13-configuration.md @@ -8,7 +8,7 @@ ## Learning Objectives -- Master all configuration options in config.json +- Master the user settings in `settings.json` - Understand every environment variable that controls Copilot CLI - Use the comprehensive CLI flags reference - Configure IDE integration, streaming, and accessibility options @@ -18,7 +18,7 @@ ### Configuration File Location -Copilot CLI stores its configuration at ~/.copilot/config.json (or the directory specified by COPILOT_HOME). +Copilot CLI stores user settings at `~/.copilot/settings.json` (or under the directory specified by `COPILOT_HOME`). ```bash # Override config directory @@ -26,11 +26,27 @@ export COPILOT_HOME=/path/to/custom/config copilot ``` -When you specify a custom config directory, the model preference stored in that directory's config.json is used instead of the default. +When you specify a custom config directory, the preferences stored in that directory's `settings.json` are used instead of the defaults. + +> [!WARNING] +> `~/.copilot/config.json` sits next to `settings.json`, but it is managed automatically by the CLI and holds your authentication token along with machine state such as `trustedFolders`. Do not print, copy, or share it โ€” this matters especially in a screen-shared workshop. Put your own preferences in `~/.copilot/settings.json`, or use `/settings` to edit them. + +### Settings Scopes + +Settings are layered. Later scopes override earlier ones, and organization-managed settings always win. + +| Scope | Location | Set with | +| --- | --- | --- | +| User | `~/.copilot/settings.json` | `/settings ` | +| Repository (shared) | `.github/copilot/settings.json` | `/settings --repo ` | +| Repository (personal, not committed) | `.github/copilot/settings.local.json` | `/settings --local ` | +| Organization-managed | Delivered by policy | Read-only; shown as `managed (read-only)` | + +Managed settings apply on top of your own; keys marked `managed (read-only)` cannot be edited from the CLI. `/model` also accepts `--repo` and `--local` to set a repository default model. ### Configuration Options Reference -All options below are set in ~/.copilot/config.json: +All options below are set in `~/.copilot/settings.json`: ```json { @@ -64,7 +80,6 @@ All options below are set in ~/.copilot/config.json: "customAgents": { "defaultLocalOnly": false }, - "trustedFolders": [], "allowedUrls": [], "deniedUrls": [], "companyAnnouncements": [] @@ -78,6 +93,10 @@ All options below are set in ~/.copilot/config.json: | `mouse` | bool | `true` | Mouse support | | `banner` | string | `"once"` | Startup banner: `"always"`, `"never"`, or `"once"` | | `beep` | bool | `false` | Terminal beep when user attention is required | +| `beepOnSchedule` | bool | `true` | Beep when a scheduled `/every` or `/after` run finishes (only when `beep` is enabled) | +| `notifications` | bool | `false` | Show OS notifications when attention is required and when the agent finishes | +| `showTipsOnStartup` | bool | `true` | Show a random command tip when the CLI starts | +| `commandHistoryMaxSize` | number | `50` | Prompts kept for `Ctrl+R` history search (integer between `1` and `1000`) | | `stream` | bool | `true` | Enable response streaming | | `autoUpdate` | bool | `true` | Auto-download CLI updates (disabled in CI by default) | | `bashEnv` | bool | `false` | Source BASH_ENV in shell sessions | @@ -85,6 +104,9 @@ All options below are set in ~/.copilot/config.json: | `compactPaste` | bool | `true` | Collapse large pasted content (>10 lines) into compact tokens | | `copyOnSelect` | bool | macOS: `true`, else: `false` | Auto-copy text selection to clipboard | | `renderMarkdown` | bool | `true` | Render markdown formatting in terminal output | +| `scrollbar` | bool | `true` | Show the scrollbar in scrollable views | +| `inlineImages` | bool | `true` | Render images inline using the Kitty graphics protocol on supporting terminals | +| `inlineImageLiveWindow` | number | `50` | Maximum inline images kept resident in the terminal; `0` disables the cap | | `screenReader` | bool | `false` | Enable screen reader optimizations | | `streamerMode` | bool | `false` | Hide preview model names and quota details (for streaming/screen sharing) | | `memory` | bool | `true` | Enable agentic memory (cross-session fact recall); toggle with `/memory on\|off` | @@ -94,18 +116,113 @@ All options below are set in ~/.copilot/config.json: | `logLevel` | string | `"default"` | Log level: `"none"`, `"error"`, `"warning"`, `"info"`, `"debug"`, `"all"` | | `keepAlive` | string | `"off"` | Prevent system sleep: `"off"`, `"on"`, or `"busy"` (busy = only while agent is working) | | `continueOnAutoMode` | bool | `false` | Auto-switch to auto mode on rate limit errors; does not apply to global limits | +| `stayInAutopilot` | bool | `true` | Stay in autopilot mode after an autopilot task completes | +| `effortLevel` | string | (varies) | Reasoning effort level; also set with `--effort` / `--reasoning-effort` | +| `contextTier` | string | `"default"` | Context window tier for tiered-pricing models: `"default"` or `"long_context"` | | `respectGitignore` | bool | `true` | Exclude gitignored files from the `@` file mention picker | | `disableAllHooks` | bool | `false` | Disable all hooks (repo-level and user-level) | | `ide.autoConnect` | bool | `true` | Auto-connect to IDE workspace on startup | | `ide.openDiffOnEdit` | bool | `true` | Open file edit diffs in connected IDE for approval | | `customAgents.defaultLocalOnly` | bool | `false` | Default to local agents only (skip remote org/enterprise agents) | -| `trustedFolders` | array | `[]` | Folders granted read/execute permission | | `allowedUrls` | array | `[]` | URLs/domains allowed without prompting (supports wildcards like `*.github.com`) | | `deniedUrls` | array | `[]` | URLs/domains denied access (takes precedence over allowed) | | `companyAnnouncements` | array | `[]` | Custom startup messages (one randomly selected per session) | -| `statusLine` | object | (none) | Custom status line config with `type`, `command`, and optional `padding` | +| `statusLine` | object | (none) | Custom status line config with `type`, `command`, `padding`, and `refreshInterval` | +| `tabs` | object | (none) | Home screen tab bar: `enabled`, `sort`, and `hide` | +| `proxyUrl` | string | (none) | Proxy URL for HTTP(S) requests; overridden by `HTTP_PROXY` / `HTTPS_PROXY` | +| `proxyKerberosServicePrincipal` | string | (none) | SPN for Kerberos/Negotiate proxy auth; overridden by `COPILOT_PROXY_KERBEROS_SPN` | | `powershellFlags` | array | `["-NoProfile", "-NoLogo"]` | Flags passed to PowerShell (pwsh) on startup (Windows only) | +#### Discovery and Extension Settings + +| Option | Type | Description | +|--------|------|-------------| +| `skillDirectories` | array | Extra directories to search for skills | +| `disabledSkills` | array | Skill names to keep from loading | +| `disabledHooks` | array | Hook names to keep from running | +| `hooks` | object | Inline hook definitions keyed by event name (same schema as `.github/hooks/*.json`) | +| `disabledMcpServers` | array | MCP servers to keep from starting | +| `enabledMcpServers` | array | MCP servers to start explicitly | +| `enabledPlugins` | array | Plugins enabled for this user | +| `extraKnownMarketplaces` | array | Additional trusted plugin marketplaces | +| `strictKnownMarketplaces` | bool | Restrict plugin installs to known marketplaces | +| `extensions.disabledExtensions` | array | CLI extensions to keep from loading | +| `githubMcpToolsets` / `githubMcpTools` | array | Toolsets and tools enabled on the built-in GitHub MCP server | +| `enableAllGithubMcpTools` | bool | Enable every GitHub MCP server tool instead of the default subset | + +#### Subagent Settings + +| Option | Type | Description | +|--------|------|-------------| +| `subagents.agents.` | object | Per-subagent `model`, `effortLevel`, and `contextTier`; each accepts `"inherit"` | +| `subagents.disabledSubagents` | array | Subagents to keep from running | +| `subagents.maxConcurrency` | number | Maximum subagents running at once | +| `subagents.maxDepth` | number | Maximum subagent nesting depth | + +Configure these interactively with `/subagents`. + +#### Footer Settings + +`footer.show*` keys toggle individual status bar items. Configure them interactively with `/footer`. + +| Option | Shows | +|--------|-------| +| `footer.showModelEffort` | Active model and reasoning effort | +| `footer.showDirectory` | Working directory | +| `footer.showBranch` | Current git branch | +| `footer.showContextWindow` | Context window usage | +| `footer.showQuota` | Remaining plan quota | +| `footer.showAiUsed` | AI credits used this session | +| `footer.showAgent` | Active custom agent | +| `footer.showCodeChanges` | Lines added/removed | +| `footer.showUsername` | Logged-in GitHub user | +| `footer.showSandbox` | Command sandboxing status | +| `footer.showYolo` | Allow-all/YOLO status | +| `footer.showCiStatus` | CI status for the current branch | +| `footer.showSchedules` | Pending `/after` and `/every` schedules | +| `footer.showPullRequest` | Pull request for the current branch | +| `footer.showCustom` | Custom `statusLine` output | + +#### Permission Settings + +| Option | Type | Description | +|--------|------|-------------| +| `permissions.allow` | array | Tool patterns allowed without prompting | +| `permissions.ask` | array | Tool patterns that always prompt | +| `permissions.deny` | array | Tool patterns always refused (takes precedence) | + +#### Command Sandboxing Settings + +Command sandboxing is experimental: enable experimental features, then use `/sandbox` to view or configure the policy. All keys live under `sandbox` in `settings.json`. See `copilot help sandbox`. + +| Option | Type | Description | +|--------|------|-------------| +| `sandbox.enabled` | bool | Whether shell commands run inside an OS-level sandbox | +| `sandbox.addCurrentWorkingDirectory` | bool | Grant read/write access to the current working directory | +| `sandbox.allowDevToolAccess` | bool | Auto-grant access to dev-tool caches, toolchains, and registry config | +| `sandbox.allowBypass` | bool | Allow a per-command escape hatch out of the sandbox | +| `sandbox.gitAuth` / `sandbox.ghAuth` | bool | Inject git and `gh` credentials into sandboxed commands | +| `sandbox.sandboxMcpServers` | bool | Spawn local (stdio) MCP servers inside the sandbox | +| `sandbox.sandboxLspServers` | bool | Spawn language servers inside the sandbox | +| `sandbox.userPolicy.filesystem.readwritePaths` | array | Extra paths granted read/write | +| `sandbox.userPolicy.filesystem.readonlyPaths` | array | Extra paths granted read-only | +| `sandbox.userPolicy.filesystem.deniedPaths` | array | Paths denied outright | +| `sandbox.userPolicy.filesystem.clearPolicyOnExit` | bool | Reset the stored filesystem policy when the session ends | +| `sandbox.userPolicy.network.allowOutbound` | bool | Allow outbound network connections | +| `sandbox.userPolicy.network.allowLocalNetwork` | bool | Allow connections to the local network | +| `sandbox.userPolicy.network.proxy.url` | string | Proxy URL for sandboxed network access | +| `sandbox.userPolicy.network.proxy.username` / `.password` | string | Proxy credentials (kept out of the URL) | +| `sandbox.userPolicy.seatbelt.keychainAccess` | bool | Allow system keychain access from inside the sandbox (macOS) | + +#### Voice Settings + +| Option | Type | Description | +|--------|------|-------------| +| `voice.enabled` | bool | Enable voice mode (dictation) | +| `voice.selectedModel` | string | Transcription model used by voice mode | + +> Run `copilot help config` for the authoritative settings reference, or `/settings` to open the settings dialog and browse every key with its effective value and default. + ### Environment Variables Reference | Variable | Description | Precedence | @@ -129,14 +246,56 @@ All options below are set in ~/.copilot/config.json: | `COPILOT_PROVIDER_API_KEY` | API key for custom provider | -- | | `PLAIN_DIFF` | Set "true" to disable rich diff rendering | -- | | `USE_BUILTIN_RIPGREP` | Set "false" to use PATH ripgrep instead of bundled | -- | +| `USE_TGREP` | Set "true" to always enable tgrep indexed search, "false" to force ripgrep | -- | +| `USE_TGREP_WARM_START` | Set "true" to block startup until the tgrep index is ready | -- | | `NO_COLOR` | Disable colored output (standard convention) | -- | -| `COLORFGBG` | Fallback for dark/light background detection ("fg;bg" format) | -- | +| `COPILOT_DISABLE_TERMINAL_TITLE` | Disable updating the terminal tab/window title | -- | +| `COPILOT_INLINE_IMAGE_LIMIT` | Override the `inlineImageLiveWindow` setting | -- | +| `COPILOT_SKILLS_DIRS` | Additional directories to search for skills | -- | +| `COPILOT_PLUGIN_DIR_ONLY` | Load plugins only from directories passed with `--plugin-dir` | -- | +| `COPILOT_HOOK_ALLOW_LOCALHOST` | Allow hooks to call localhost endpoints | -- | +| `COPILOT_HOOK_ALLOW_HTTP_AUTH_HOOKS` | Allow hooks that send HTTP auth headers | -- | | `HTTP_PROXY` | HTTP proxy URL for network requests | -- | | `HTTPS_PROXY` | HTTPS proxy URL for network requests | -- | | `NO_PROXY` | Comma-separated hosts to bypass proxy | -- | +| `COPILOT_PROXY_KERBEROS_SPN` | Service principal name for Kerberos/Negotiate proxy auth | Over `proxyKerberosServicePrincipal` | | `CI`, `BUILD_NUMBER`, `RUN_ID`, `SYSTEM_COLLECTIONURI` | CI environment detection (disables auto-update) | -- | -> **Tip:** Run `copilot help environment` for the complete, up-to-date list of environment variables, including all `COPILOT_PROVIDER_*` and `OTEL_*` variables. +#### Custom Model Provider (BYOK) Variables + +| Variable | Description | +|----------|-------------| +| `COPILOT_PROVIDER_BEARER_TOKEN` | Bearer token for the provider; takes precedence over `COPILOT_PROVIDER_API_KEY` | +| `COPILOT_PROVIDER_WIRE_API` | API format: `completions` (default) or `responses` | +| `COPILOT_PROVIDER_TRANSPORT` | Transport: `http` (default) or `websockets` | +| `COPILOT_PROVIDER_AZURE_API_VERSION` | Azure API version when using provider type `azure` | +| `COPILOT_PROVIDER_MODEL_ID` | Well-known model ID used for agent configuration and token limits | +| `COPILOT_PROVIDER_WIRE_MODEL` | Model name sent to the provider API for inference | +| `COPILOT_PROVIDER_MAX_PROMPT_TOKENS` | Maximum prompt tokens for the BYOK model | +| `COPILOT_PROVIDER_MAX_OUTPUT_TOKENS` | Maximum output tokens for the BYOK model | +| `COPILOT_PROVIDER_HEADERS` | Newline-separated `Name: Value` headers sent only to the BYOK endpoint | + +#### OpenTelemetry / Monitoring Variables + +Run `copilot help monitoring` for configuration examples. + +| Variable | Description | +|----------|-------------| +| `COPILOT_OTEL_ENABLED` | Set "true" to explicitly enable OpenTelemetry instrumentation | +| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP endpoint URL; setting it enables OTel automatically | +| `COPILOT_OTEL_EXPORTER_TYPE` | Exporter backend: `otlp-http` (default) or `file` | +| `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP HTTP protocol: `http/json` (default) or `http/protobuf` | +| `COPILOT_OTEL_FILE_EXPORTER_PATH` | File path for JSON-lines output; setting it enables OTel automatically | +| `COPILOT_OTEL_SOURCE_NAME` | Instrumentation scope name; defaults to `github.copilot` | +| `OTEL_SERVICE_NAME` | Service name in resource attributes; defaults to `github-copilot` | +| `OTEL_RESOURCE_ATTRIBUTES` | Extra resource attributes as comma-separated `key=value` pairs | +| `OTEL_EXPORTER_OTLP_HEADERS` | Authentication headers for the OTLP exporter | +| `OTEL_EXPORTER_OTLP_CERTIFICATE` | PEM file with extra CA certificates to trust for the OTLP endpoint | +| `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` / `OTEL_EXPORTER_OTLP_CLIENT_KEY` | Client certificate and key for mutual TLS (both required) | +| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | Set "true" to capture full prompt/response content | +| `OTEL_LOG_LEVEL` | OTel diagnostic log level: `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `VERBOSE`, or `ALL` | + +> **Tip:** Run `copilot help environment` for the authoritative list of environment variables. ### CLI Flags Quick Reference @@ -146,36 +305,16 @@ All options below are set in ~/.copilot/config.json: | `-i, --interactive ` | Interactive mode with auto-executed prompt | | `-s, --silent` | Output only agent response (no stats) | | `-v, --version` | Show version information | +| `-C ` | Change working directory before doing anything else | | `-n, --name ` | Set a name for the new session | +| `--mode ` | Set the initial agent mode: `interactive`, `plan`, or `autopilot` | +| `--plan` | Start in plan mode | | `--model ` | Set AI model | | `--reasoning-effort ` | Set reasoning effort level for model | | `--effort ` | Shorthand for `--reasoning-effort` | | `--context ` | Set context window tier (`default` or `long_context`) | | `--enable-reasoning-summaries` | Request reasoning summaries for OpenAI models | | `--connect[=sessionId]` | Connect directly to a remote session | - -### The `/env` Command - -Use `/env` inside an interactive session to see a comprehensive view of the loaded environment: - -``` -/env -``` - -This displays: -- Active instruction files and their sources -- Loaded MCP servers and their status -- Available skills (project, personal, built-in) -- Installed plugins -- Current model and configuration directory - -### The `copilot help monitoring` Topic - -```bash -copilot help monitoring -``` - -This displays documentation on configuring OpenTelemetry for Copilot CLI observability, including OTLP exporter settings, span attributes, and monitoring backend integration. | `--resume [sessionId]` | Resume previous session | | `--continue` | Resume most recent session | | `--yolo` / `--allow-all` | Enable all permissions | @@ -198,6 +337,7 @@ This displays documentation on configuring OpenTelemetry for Copilot CLI observa | `--max-ai-credits ` | Set a session AI credit limit | | `--session-id ` | Resume a session/task by ID or set a UUID for a new session | | `--remote-export` | Export session to GitHub web/mobile read-only | +| `--remote` | Enable remote control of your session from GitHub web and mobile | | `--no-remote` | Disable remote control | | `--no-remote-export` | Disable remote export | | `--enable-memory` | Enable memory in prompt mode | @@ -222,27 +362,54 @@ This displays documentation on configuring OpenTelemetry for Copilot CLI observa | `--banner` | Show startup banner | | `--no-color` | Disable color output | | `--no-auto-update` | Disable auto-update | -| `--mouse [on\|off]` | Toggle mouse support | +| `--mouse [on\|off]` | Enable or disable mouse support in alt screen mode | +| `--no-mouse` | Disable mouse support in alt screen mode | | `--bash-env [on\|off]` | Toggle BASH_ENV support | | `--experimental` / `--no-experimental` | Toggle experimental features | | `--screen-reader` | Enable screen reader optimizations | | `--plain-diff` | Disable rich diff rendering | +### The `/env` Command + +Use `/env` inside an interactive session to see a comprehensive view of the loaded environment: + +``` +/env +``` + +This displays: +- Active instruction files and their sources +- Loaded MCP servers and their status +- Available skills (project, personal, built-in) +- Installed plugins +- Current model and configuration directory + +### The `copilot help monitoring` Topic + +```bash +copilot help monitoring +``` + +This displays documentation on configuring OpenTelemetry for Copilot CLI observability, including OTLP exporter settings, span attributes, and monitoring backend integration. + ## Hands-On Exercises ### Exercise 1: Explore Your Configuration -**Goal:** Understand and modify config.json settings. +**Goal:** Understand and modify your `settings.json` settings. + +> [!WARNING] +> Do not `cat` `~/.copilot/config.json`. It is managed automatically and contains your authentication token โ€” printing it in a shared terminal exposes a live credential. **Steps:** -1. View your current configuration: +1. View your current user settings: ```bash - cat ~/.copilot/config.json | jq . + cat ~/.copilot/settings.json | jq . ``` -2. Check the available config options: +2. Check the available settings: ```bash copilot help config @@ -256,18 +423,40 @@ This displays documentation on configuring OpenTelemetry for Copilot CLI observa } ``` + Or set it from inside a session, which writes to `settings.json` for you: + + ```bash + copilot + ``` + + ``` + /settings mouse on + /settings show mouse + ``` + 4. Start Copilot and verify the change takes effect. -5. Try toggling options via CLI flags (flags persist to config): +5. Try toggling options via CLI flags (flags persist to your settings): ```bash - # These flags update config.json automatically + # These flags update settings.json automatically copilot --mouse off copilot --bash-env on ``` +6. Target repository scope instead of your user scope: + + ```bash + copilot + ``` + + ``` + /settings --repo theme dim # writes .github/copilot/settings.json + /settings --local theme github # writes .github/copilot/settings.local.json + ``` + **Expected Outcome:** -You can view, modify, and verify config options and understand that certain CLI flags persist their values to config. +You can view, modify, and verify settings at user and repository scope, and you understand that certain CLI flags persist their values to `settings.json`. ### Exercise 2: Environment Variable Control @@ -297,6 +486,9 @@ You can view, modify, and verify config options and understand that certain CLI echo "Always use TypeScript" > /tmp/team-instructions/AGENTS.md export COPILOT_CUSTOM_INSTRUCTIONS_DIRS="/tmp/team-instructions" copilot + ``` + + ``` /instructions ``` @@ -328,12 +520,15 @@ You can control Copilot behavior via environment variables and understand their ```bash copilot + ``` + + ``` /ide ``` 2. The `/ide` command shows connected IDE workspaces. If VS Code is running with a workspace open, Copilot auto-connects. -3. Modify IDE behavior in config: +3. Modify IDE behavior in `settings.json`: ```json { @@ -358,7 +553,7 @@ You understand how Copilot integrates with IDEs and can customize the behavior. **Steps:** -1. Enable streamer mode (hides preview model names and quota details) in config: +1. Enable streamer mode (hides preview model names and quota details) in `settings.json`: ```json { "streamerMode": true } @@ -422,9 +617,22 @@ You can configure Copilot for streaming, screen readers, and plain-text environm } ``` -3. Create a team config template and document it in your AGENTS.md. +3. Commit these as repository settings so everyone on the project picks them up: + + ```bash + copilot + ``` + + ``` + /settings --repo model auto + /settings --repo includeCoAuthoredBy on + ``` + + Shared values land in `.github/copilot/settings.json`; personal overrides that should not be committed go to `.github/copilot/settings.local.json` via `/settings --local`. + +4. Document the template in your AGENTS.md. -4. Verify the announcements appear on startup: +5. Verify the announcements appear on startup: ```bash copilot @@ -432,7 +640,7 @@ You can configure Copilot for streaming, screen readers, and plain-text environm ``` **Expected Outcome:** -You can create and distribute team-standard configurations. +You can create and distribute team-standard configurations across user and repository scopes. ### Exercise 6: Logging and Debugging @@ -446,12 +654,14 @@ You can create and distribute team-standard configurations. copilot --log-level debug ``` -2. Set a custom log directory: +2. Capture everything into a custom log directory: ```bash - copilot --log-dir ./my-logs + copilot --log-level all --log-dir ./my-logs ``` + Valid levels are `none`, `error`, `warning`, `info`, `debug`, `all`, and `default`. The equivalent setting is `logLevel`. + 3. After a session, inspect the logs: ```bash @@ -470,9 +680,52 @@ You can create and distribute team-standard configurations. **Expected Outcome:** You can enable detailed logging and understand the log directory structure. +### Exercise 7: Session Limits and AI Credits + +**Goal:** Cap how many AI credits a session can consume. + +**Steps:** + +1. Read the reference topics: + + ```bash + copilot help limits + copilot help billing + ``` + +2. Start a session with an initial limit (the minimum is 30 AI credits): + + ```bash + copilot --max-ai-credits 30 + ``` + +3. Inspect or change the limit from inside the session: + + ``` + /limits + /limits set max-ai-credits 50 + ``` + +4. Watch usage in the footer and with `/usage`. Enable the relevant footer items if they are hidden: + + ``` + /footer + ``` + +5. Remove the limit when you are done: + + ``` + /limits unset max-ai-credits + ``` + +**Expected Outcome:** +You can set, inspect, and clear a session AI credit limit, and you understand it is a soft cap โ€” usage is only known after a model response returns, so one call can exceed the limit before the next call is blocked. + ## Summary -- โœ… config.json centralizes all CLI preferences +- โœ… `settings.json` centralizes all CLI preferences; `/settings` reads and writes it +- โœ… `config.json` is machine-managed and holds credentials โ€” never print or share it +- โœ… Settings layer across user, repository (`--repo`), personal repository (`--local`), and organization-managed scopes - โœ… Config options cover model, theme, streaming, mouse, and more - โœ… `compactPaste` auto-collapses large pastes into compact tokens - โœ… `copyOnSelect` enables clipboard integration @@ -501,6 +754,11 @@ You can enable detailed logging and understand the log directory structure. - โœ… BYOK support via `COPILOT_PROVIDER_*` env vars โ€” run `copilot help providers` for details - โœ… `COPILOT_OFFLINE` enables offline mode with local model providers - โœ… `COPILOT_GH_HOST` overrides GitHub hostname for Copilot CLI only +- โœ… `footer.show*` settings control individual status bar items +- โœ… `sandbox.*` settings define the command sandboxing policy (experimental; see `copilot help sandbox`) +- โœ… Session limits are opt-in via `--max-ai-credits` and `/limits` (soft cap, minimum 30 AI credits) +- โœ… OpenTelemetry is configured entirely through `COPILOT_OTEL_*` and `OTEL_*` environment variables +- โœ… `copilot help config` and `copilot help environment` are the authoritative references ## Workshop Complete! ๐ŸŽ‰