diff --git a/.vscode/.copilotignore b/.vscode/.copilotignore new file mode 100644 index 0000000..74d8496 --- /dev/null +++ b/.vscode/.copilotignore @@ -0,0 +1 @@ +- docs/**/* \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index 34d28dd..be4a9f5 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -43,18 +43,18 @@ "license": "MIT" }, "node_modules/@astrojs/internal-helpers": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.6.1.tgz", - "integrity": "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.2.tgz", + "integrity": "sha512-KCkCqR3Goym79soqEtbtLzJfqhTWMyVaizUi35FLzgGSzBotSw8DB1qwsu7U96ihOJgYhDk2nVPz+3LnXPeX6g==", "license": "MIT" }, "node_modules/@astrojs/markdown-remark": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.3.tgz", - "integrity": "sha512-DDRtD1sPvAuA7ms2btc9A7/7DApKqgLMNrE6kh5tmkfy8utD0Z738gqd3p5aViYYdUtHIyEJ1X4mCMxfCfu15w==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.6.tgz", + "integrity": "sha512-bwylYktCTsLMVoCOEHbn2GSUA3c5KT/qilekBKA3CBng0bo1TYjNZPr761vxumRk9kJGqTOtU+fgCAp5Vwokug==", "license": "MIT", "dependencies": { - "@astrojs/internal-helpers": "0.6.1", + "@astrojs/internal-helpers": "0.7.2", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", @@ -78,17 +78,17 @@ } }, "node_modules/@astrojs/node": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.3.0.tgz", - "integrity": "sha512-IV8NzGStHAsKBz1ljxxD8PBhBfnw/BEx/PZfsncTNXg9D4kQtZbSy+Ak0LvDs+rPmK0VeXLNn0HAdWuHCVg8cw==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-9.4.3.tgz", + "integrity": "sha512-P9BQHY8wQU1y9obknXzxV5SS3EpdaRnuDuHKr3RFC7t+2AzcMXeVmMJprQGijnQ8VdijJ8aS7+12tx325TURMQ==", "license": "MIT", "dependencies": { - "@astrojs/internal-helpers": "0.6.1", + "@astrojs/internal-helpers": "0.7.2", "send": "^1.2.0", "server-destroy": "^1.0.1" }, "peerDependencies": { - "astro": "^5.3.0" + "astro": "^5.7.0" } }, "node_modules/@astrojs/prism": { @@ -1352,60 +1352,60 @@ ] }, "node_modules/@shikijs/core": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.8.1.tgz", - "integrity": "sha512-uTSXzUBQ/IgFcUa6gmGShCHr4tMdR3pxUiiWKDm8pd42UKJdYhkAYsAmHX5mTwybQ5VyGDgTjW4qKSsRvGSang==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.11.0.tgz", + "integrity": "sha512-oJwU+DxGqp6lUZpvtQgVOXNZcVsirN76tihOLBmwILkKuRuwHteApP8oTXmL4tF5vS5FbOY0+8seXmiCoslk4g==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.8.1", + "@shikijs/types": "3.11.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "node_modules/@shikijs/engine-javascript": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.8.1.tgz", - "integrity": "sha512-rZRp3BM1llrHkuBPAdYAzjlF7OqlM0rm/7EWASeCcY7cRYZIrOnGIHE9qsLz5TCjGefxBFnwgIECzBs2vmOyKA==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.11.0.tgz", + "integrity": "sha512-6/ov6pxrSvew13k9ztIOnSBOytXeKs5kfIR7vbhdtVRg+KPzvp2HctYGeWkqv7V6YIoLicnig/QF3iajqyElZA==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.8.1", + "@shikijs/types": "3.11.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "node_modules/@shikijs/engine-oniguruma": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.8.1.tgz", - "integrity": "sha512-KGQJZHlNY7c656qPFEQpIoqOuC4LrxjyNndRdzk5WKB/Ie87+NJCF1xo9KkOUxwxylk7rT6nhlZyTGTC4fCe1g==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.11.0.tgz", + "integrity": "sha512-4DwIjIgETK04VneKbfOE4WNm4Q7WC1wo95wv82PoHKdqX4/9qLRUwrfKlmhf0gAuvT6GHy0uc7t9cailk6Tbhw==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.8.1", + "@shikijs/types": "3.11.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "node_modules/@shikijs/langs": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.8.1.tgz", - "integrity": "sha512-TjOFg2Wp1w07oKnXjs0AUMb4kJvujML+fJ1C5cmEj45lhjbUXtziT1x2bPQb9Db6kmPhkG5NI2tgYW1/DzhUuQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.11.0.tgz", + "integrity": "sha512-Njg/nFL4HDcf/ObxcK2VeyidIq61EeLmocrwTHGGpOQx0BzrPWM1j55XtKQ1LvvDWH15cjQy7rg96aJ1/l63uw==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.8.1" + "@shikijs/types": "3.11.0" } }, "node_modules/@shikijs/themes": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.8.1.tgz", - "integrity": "sha512-Vu3t3BBLifc0GB0UPg2Pox1naTemrrvyZv2lkiSw3QayVV60me1ujFQwPZGgUTmwXl1yhCPW8Lieesm0CYruLQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.11.0.tgz", + "integrity": "sha512-BhhWRzCTEk2CtWt4S4bgsOqPJRkapvxdsifAwqP+6mk5uxboAQchc0etiJ0iIasxnMsb764qGD24DK9albcU9Q==", "license": "MIT", "dependencies": { - "@shikijs/types": "3.8.1" + "@shikijs/types": "3.11.0" } }, "node_modules/@shikijs/types": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.8.1.tgz", - "integrity": "sha512-5C39Q8/8r1I26suLh+5TPk1DTrbY/kn3IdWA5HdizR0FhlhD05zx5nKCqhzSfDHH3p4S0ZefxWd77DLV+8FhGg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.11.0.tgz", + "integrity": "sha512-RB7IMo2E7NZHyfkqAuaf4CofyY8bPzjWPjJRzn6SEak3b46fIQyG6Vx5fG/obqkfppQ+g8vEsiD7Uc6lqQt32Q==", "license": "MIT", "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", @@ -2005,14 +2005,14 @@ } }, "node_modules/astro": { - "version": "5.12.4", - "resolved": "https://registry.npmjs.org/astro/-/astro-5.12.4.tgz", - "integrity": "sha512-ns+/KpfWToKvVf2DJTj4EIa4U59/XVBXeeq6VZUr5DXe6OZJFs8NfJi+W20nRm5nduIeBZGRzaoxPFq9lm4WEg==", + "version": "5.13.3", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.13.3.tgz", + "integrity": "sha512-V0mUOUK70UZ7xqXp5Noqse/SREU0P756KgFufBEluq5LkmBejzC2GENMUA2Na+PFwUjemElJtRlpKyrnKpFhSQ==", "license": "MIT", "dependencies": { "@astrojs/compiler": "^2.12.2", - "@astrojs/internal-helpers": "0.6.1", - "@astrojs/markdown-remark": "6.3.3", + "@astrojs/internal-helpers": "0.7.2", + "@astrojs/markdown-remark": "6.3.6", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", @@ -5272,17 +5272,17 @@ } }, "node_modules/shiki": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.8.1.tgz", - "integrity": "sha512-+MYIyjwGPCaegbpBeFN9+oOifI8CKiKG3awI/6h3JeT85c//H2wDW/xCJEGuQ5jPqtbboKNqNy+JyX9PYpGwNg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.11.0.tgz", + "integrity": "sha512-VgKumh/ib38I1i3QkMn6mAQA6XjjQubqaAYhfge71glAll0/4xnt8L2oSuC45Qcr/G5Kbskj4RliMQddGmy/Og==", "license": "MIT", "dependencies": { - "@shikijs/core": "3.8.1", - "@shikijs/engine-javascript": "3.8.1", - "@shikijs/engine-oniguruma": "3.8.1", - "@shikijs/langs": "3.8.1", - "@shikijs/themes": "3.8.1", - "@shikijs/types": "3.8.1", + "@shikijs/core": "3.11.0", + "@shikijs/engine-javascript": "3.11.0", + "@shikijs/engine-oniguruma": "3.11.0", + "@shikijs/langs": "3.11.0", + "@shikijs/themes": "3.11.0", + "@shikijs/types": "3.11.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } @@ -5304,9 +5304,9 @@ "license": "MIT" }, "node_modules/smol-toml": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.4.1.tgz", - "integrity": "sha512-CxdwHXyYTONGHThDbq5XdwbFsuY4wlClRGejfE2NtwUtiHYsP1QtNsHb/hnj31jKYSchztJsaA8pSQoVzkfCFg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.4.2.tgz", + "integrity": "sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==", "license": "BSD-3-Clause", "engines": { "node": ">= 18" diff --git a/client/playwright.config.ts b/client/playwright.config.ts index 3b62fc0..45edf48 100644 --- a/client/playwright.config.ts +++ b/client/playwright.config.ts @@ -20,7 +20,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, + workers: 5, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: 'list', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ diff --git a/docs/0-prereqs.md b/docs/0-prereqs.md index 299a91f..aa7868b 100644 --- a/docs/0-prereqs.md +++ b/docs/0-prereqs.md @@ -35,6 +35,9 @@ Next up, we will be using a codespace to complete the lab exercises. [GitHub Cod The creation of the codespace will take several minutes, although it's still far quicker than having to manually install all the services! That said, we can use this time to take advantage of our ability to assign tasks to GitHub Copilot which it can perform asynchronously, which we'll turn our attention to next! +> [!IMPORTANT] +> We will return to the codespace in a future exercise. For the time being, leave it open in a tab in your browser. + ## Summary Congratulations, you have created a copy of the lab repository! You also began the creation process of your codespace, which you'll use when you begin writing code. We're going to return back to this after the next lesson, so don't worry. diff --git a/docs/1-copilot-coding-agent.md b/docs/1-copilot-coding-agent.md index d0092d3..1e539ea 100644 --- a/docs/1-copilot-coding-agent.md +++ b/docs/1-copilot-coding-agent.md @@ -28,13 +28,15 @@ These are both examples of tasks which can quickly find themselves deprioritized While it can often feel like it, there is no magic in GitHub Copilot. There are no magic solutions available, where you can with just a couple of sentences snap your fingers and let AI perform the entire task for you. In fact, even seemingly straight-forward operations can often have fair amount of complexity when we peel back the layers. -As a result, we want to [be mindful about how we approach assigning tasks to Copilot coding agent][coding-agent-best-practices], and that working with Copilot as an AI pair programmer is typically the best approach. The approach you take tasks big and small is the same with or without Copilot - work in stages, learn, experiment, and adapt accordingly. As always, the fundamentals of software development do not change with the addition of generative AI. +As a result, we want to [be mindful about how we approach assigning tasks to Copilot coding agent][coding-agent-best-practices]. Working with Copilot as an AI pair programmer is typically the best approach. Approach tasks, big and small, following the same strategy you would without Copilot - work in stages, learn, experiment, and adapt accordingly. + +As always, the fundamentals of software development do not change with the addition of generative AI. ## Setting up the dev environment for the Copilot coding agent Creating code, regardless of who's involved, typically requires a specific environment and some setup scripts to be run to ensure everything is in a good state. This holds true when assigning tasks to Copilot, which is performing tasks in a similar fashion to a SWE. -[Copilot coding agent supports a special workflow][setup-workflow], set in the **.github/workflows/copilot-setup-steps.yml** file, to run before it gets to work. This enables it to have access to the required development tools and dependencies. We pre-configured this ahead of the lab to help the lab flow and allow this learning opportunity. It makes sure that Copilot had access to Python, Node.JS, and the required dependencies for the client and server: +Coding agent uses [GitHub Actions][github-actions] for its environment when doing its work. You can customize this environment by creating a [special setup workflow][setup-workflow], configured in the **.github/workflows/copilot-setup-steps.yml** file, to run before it gets to work. This enables it to have access to the required development tools and dependencies. We pre-configured this ahead of the lab to help the lab flow and allow this learning opportunity. It makes sure that Copilot had access to Python, Node.JS, and the required dependencies for the client and server: ```yaml name: "Copilot Setup Steps" @@ -108,14 +110,17 @@ While every developer and organization understands the importance of documentati ![Copilot uses the eyes emoji to indicate it's working on the issue](images/ex4-issue-eyes.png) 11. Select the **Pull Requests** tab. -12. Open the newly generated issue, which will be titled something similar to **[WIP]: Code lacks documentation**. +12. Open the newly generated pull request (PR), which will be titled something similar to **[WIP]: Code lacks documentation**. 13. After a few minutes, you should see that Copilot has created a todo list. -14. Review the list and the tasks it's going to complete. -15. Scroll down the pull request timeline, and you should see an update that Copilot has started working on the issue. -16. Select the **View session** button. - ![Copilot session view](images/ex4-view-session.png) +> [!NOTE] +> It make take several minutes for the todo list from Copilot to appear in the PR. Copilot is creating its environment (running the workflow highlighted previously), analyzing the project, and determining the best approach to tackling the problem. +14. Review the list and the tasks it's going to complete. +15. Scroll down the pull request timeline, and you should see an update that Copilot has started working on the issue. +16. Select the **View session** button. + + ![Copilot session view](images/ex4-view-session.png) > [!IMPORTANT] > You may need to refresh the window to see the updated indicator. @@ -158,20 +163,7 @@ Shortly after, you should see a set of 👀 on the first comment in the issue, i ![Copilot uses the eyes emoji to indicate it's working on the issue](images/ex4-issue-eyes.png) -> [!IMPORTANT] -> You may need to refresh the window to see the updated indicator. - -13. Select the **Pull Requests** tab. -14. Open the newly generated PR, which will be titled something similar to **[WIP]: Add endpoints to create and edit games**. -15. After a few minutes, Copilot will update the PR with a checklist of the tasks its going to perform. It will use this checklist to indicate to the outside world its progress. -16. Scroll down the pull request timeline, and you should see an update that Copilot has started working on the issue. -17. Select the **View session** button. - - ![Copilot session view](images/ex4-view-session.png) - -18. Notice that you can scroll through the live session, and how Copilot is solving the problem. That includes exploring the code and understanding the state, how Copilot pauses to think and decide on the appropriate plan and also creating code. - -Copilot is now diligently working on your request! Copilot coding agent works in a similar fashion to a SWE, so we don't need to actively monitor it, but instead review once it's completed. Let's turn our attention to writing code and adding other features. +Copilot is now diligently working on your second request! Copilot coding agent works in a similar fashion to a SWE, so we don't need to actively monitor it, but instead review once it's completed. Let's turn our attention to writing code and adding other features. ## Summary and next steps @@ -197,11 +189,12 @@ With coding agent working diligently in the background, we can now turn our atte | [← Prerequisites][previous-lesson] | [Next lesson: MCP servers →][next-lesson] | |:--|--:| -[coding-agent-overview]: https://docs.github.com/en/copilot/using-github-copilot/coding-agent/about-assigning-tasks-to-copilot#overview-of-copilot-coding-agent -[coding-agent-mcp]: https://docs.github.com/en/copilot/how-tos/agents/copilot-coding-agent/extending-copilot-coding-agent-with-mcp -[assign-issue]: https://docs.github.com/en/copilot/using-github-copilot/coding-agent/using-copilot-to-work-on-an-issue -[setup-workflow]: https://docs.github.com/en/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks#pre-installing-dependencies-in-github-copilots-environment -[copilot-agents]: https://docs.github.com/en/copilot/using-github-copilot/coding-agent/about-assigning-tasks-to-copilot -[coding-agent-best-practices]: https://docs.github.com/en/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks +[coding-agent-overview]: https://docs.github.com/copilot/using-github-copilot/coding-agent/about-assigning-tasks-to-copilot#overview-of-copilot-coding-agent +[coding-agent-mcp]: https://docs.github.com/copilot/how-tos/agents/copilot-coding-agent/extending-copilot-coding-agent-with-mcp +[assign-issue]: https://docs.github.com/copilot/using-github-copilot/coding-agent/using-copilot-to-work-on-an-issue +[setup-workflow]: https://docs.github.com/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks#pre-installing-dependencies-in-github-copilots-environment +[copilot-agents]: https://docs.github.com/copilot/using-github-copilot/coding-agent/about-assigning-tasks-to-copilot +[coding-agent-best-practices]: https://docs.github.com/copilot/using-github-copilot/coding-agent/best-practices-for-using-copilot-to-work-on-tasks +[github-actions]: https://docs.github.com/actions [next-lesson]: ./2-mcp.md [previous-lesson]: ./0-prereqs.md diff --git a/docs/2-mcp.md b/docs/2-mcp.md index 804a860..e0df5ba 100644 --- a/docs/2-mcp.md +++ b/docs/2-mcp.md @@ -63,31 +63,24 @@ Once you have the extension installed, you may need to authenticate with your Gi 1. Return to your codespace. 2. Select the **Copilot Chat** icon at the top of your codespace. 3. Type a message like "Hello world" in the Copilot Chat window and press enter. This should activate Copilot Chat. - - ![Example of Copilot Chat activation](images/copilot-chat-activation.png) - 4. Alternatively, if you are not authenticated you will be prompted to sign in to your GitHub account. Follow the instructions to authenticate. ![Example of Copilot Chat authentication prompt](images/copilot-authentication.png) 5. After authentication, you should see the Copilot Chat window appear. - ![Example of Copilot Chat window](images/copilot-chat-window.png) - 6. Switch to agent mode by selecting the dropdown in the Copilot Chat window and selecting **Agent**. ![Example of switching to agent mode](images/copilot-agent-mode-dropdown.png) -7. Set the model to **Claude 3.5 Sonnet**. +7. Set the model to **Claude Sonnet 4**. - ![Example of selecting the Claude 3.5 Sonnet model](images/copilot-agent-mode-model.png) + ![Example of selecting the Claude Sonnet 4 model](images/copilot-agent-mode-model.png) > [!IMPORTANT] -> The authors of this lab are not indicating a preference towards one model or another. When building this lab, we used Claude 3.5 Sonnet, and as such are including that in the instructions. The hope is the code suggestions you receive will be relatively consistent to ensure a good experience. However, because LLMs are probabilistic, you may notice the suggestions received differ from what is indicated in the lab. This is perfectly normal and expected. +> The authors of this lab are not indicating a preference towards one model or another. When building this lab, we used Claude Sonnet 4, and as such are including that in the instructions. The hope is the code suggestions you receive will be relatively consistent to ensure a good experience. However, because LLMs are probabilistic, you may notice the suggestions received differ from what is indicated in the lab. This is perfectly normal and expected. -8. The chat pane should update to indicate that you are now in agent mode. You should see a tools icon, showing that we can configure tools for GitHub Copilot to use. - - ![Example of Copilot Chat agent mode with tools icon](images/copilot-agent-mode.png) +8. The chat pane should update to indicate that you are now in agent mode. You should see a tools icon on the same line as the mode and model, which you utilized earlier, showing that we can configure tools for GitHub Copilot to use. Typically, the number of tools available will be set to 0 when setting up a new project, as we have not configured any MCP servers yet. But to help you get started, we have created a **.vscode/mcp.json** file with an example configuration for the [GitHub MCP server][github-mcp-server]. Let's go and explore that next. @@ -100,12 +93,12 @@ The **.vscode/mcp.json** file is used to configure the MCP servers that are avai ```json { - "servers": { - "github": { - "type": "http", - "url": "https://api.githubcopilot.com/mcp/" - } + "servers": { + "github": { + "type": "http", + "url": "https://api.githubcopilot.com/mcp/" } + } } ``` @@ -115,6 +108,8 @@ The MCP server configuration is defined in the **servers** section of the **mcp. To utilize an MCP server it needs to be "started". This will allow GitHub Copilot to communicate with the server and perform the tasks you request. +> [!NOTE] The exact authentication flow may vary a little bit. + 1. Inside VS Code, open **.vscode/mcp.json**. 2. To start the GitHub MCP server, select **Start** above the GitHub server. @@ -133,30 +128,21 @@ To utilize an MCP server it needs to be "started". This will allow GitHub Copilo ![A popup showing the authorization for visual-studio-code app](images/ex2-mcp-auth-vscode.png) 6. After navigating back to the GitHub Codespace, you should see that the GitHub MCP server has started. You can check this in two places: - - The line in **.vscode/mcp.json** which previously said start. It should now present several options, and show a number of tools available. + - The line in **.vscode/mcp.json** which previously said start should now present several options, and show a number of tools available. - Select the tools icon in the Copilot Chat pane to see the tools available. Scroll down the list that appears at the top of the screen, and you should see a list of tools from the GitHub MCP server. - ![Example of the MCP server started with tools available](images/ex2-mcp-server-started.png) - That's it! You can now use Copilot Chat in agent mode to create issues, manage pull requests, and more. -> [!IMPORTANT] -> If you have any issues with this MCP server configuration, there are alternate configuration options in the [GitHub MCP server][github-mcp-server] repository using local or remote MCP. If you opt for a configuration that requires authentication via a GitHub Personal Access Token (PAT), make sure that you do not share it with anyone. Treat it like a password and keep it secure. That means you should not check it into source control or share it with anyone else. -> -> Because it is a sensitive password, **DO NOT** paste it into the **mcp.json** file. Instead use the **inputs** property to pass the token as an input variable. Published tokens is one of the leading causes of security breaches. - ## Creating a backlog of tasks Now that you have set up the GitHub MCP server, you can use Copilot Agent mode to create a backlog of tasks for use in the rest of the lab. -1. Return to the Copilot Chat pane. Select **Agent** from the dropdown list. Set the model to **Claude 3.5 Sonnet**. - - ![Example of the Copilot Chat pane with Agent Mode selected](images/copilot-agent-mode-dropdown.png) +1. Return to the Copilot Chat pane. Ensure **Agent** is selected for the mode and **Claude Sonnet 4** is selected for the model. -2. Type or paste the following prompt to create the issues we'll be working on in the lab, replacing **** with the organization/name of your repository: +2. Type or paste the following prompt to create the issues we'll be working on in the lab: ```markdown - In , create GitHub issues for our Tailspin Toys backlog in the repo. Each issue should include: + In my GitHub repo, create GitHub issues for our Tailspin Toys backlog. Each issue should include: - A clear title - A brief description of the task and why it is important to the project - A checkbox list of acceptance criteria diff --git a/docs/3-custom-instructions.md b/docs/3-custom-instructions.md index 0d53fe6..9bea6af 100644 --- a/docs/3-custom-instructions.md +++ b/docs/3-custom-instructions.md @@ -17,7 +17,8 @@ As any good dev shop, Tailspin Toys has a set of guidelines and requirements for - API always needs unit tests. - UI should be in dark mode and have a modern feel. -- Documentation should be added to code in the form of docstrings and header comments. +- Documentation should be added to code in the form of docstrings. +- A block of comments should be added to the head of each file describing what the file does. Through the use of instruction files you'll ensure Copilot has the right information to perform the tasks in alignment with the practices highlighted. @@ -43,7 +44,7 @@ There are two types of instructions files: - **\*.instructions.md** files can be created for specific tasks or file types. You can use **.instructions.md** files to provide guidelines for particular languages (like Python or TypeScript), or for tasks like creating a React component or a new instance of a repository pattern. > [!NOTE] -> When working in your IDE, instructions files are only used for code generation in Copilot Chat, and not used for code completions. +> When working in your IDE, instructions files are only used for code generation in Copilot Chat, and not used for code completions or next edit suggestions. ## Use GitHub Copilot Chat before updating custom instructions @@ -51,37 +52,32 @@ To see the impact of custom instructions, we will start by sending a prompt with 1. Return to your codespace. 2. Close any open files in your codespace from the previous exercises. This will ensure Copilot has the context we want it to have. -3. Open **server/routes/publishers.py**, an empty file. -4. Open **Copilot chat** by selecting the Copilot icon towards the top of your codespace. -5. Create a new chat session by selecting the **New Chat** button, which will remove any previous context. - - ![Screenshot of the New Chat button being highlighted in the Copilot Chat panel](images/copilot-new-chat.png) - +3. Open `server/routes/publishers.py`, an empty file. +4. If **Copilot chat** is not already open, open it by selecting the Copilot icon towards the top of your codespace. +5. Create a new chat session by typing `/clear` into the chat window and selecting Enter (or return on a Mac). 6. Select **Ask** from the modes dropdown. - - ![Screenshot of the Ask mode being highlighted in the Copilot Chat panel](images/copilot-chat-ask.png) - 7. Send the following prompt to create a new endpoint to return all publishers: ```plaintext Create a new endpoint to return a list of all publishers. It should return the name and id for all publishers. ``` -8. Notice the generated code includes [type hints][python-type-hints] because, as we'll see, our custom instructions includes the directive to include them. -9. Notice the generated code **is missing** either a docstring or a comment header - or both! +8. Copilot explores the project to learn how best to implement the code, and generates a list of suggestions, which may include code for `publishers.py`, `app.py`, and tests to ensure the new code runs correctly. +9. Explore the code, noticing the generated code includes [type hints][python-type-hints] because, as we'll see, our custom instructions includes the directive to include them. +10. Notice the generated code **is missing** either a docstring or a comment header - or both! > [!IMPORTANT] > As highlighted previously, GitHub Copilot and LLM tools are probabilistic, not deterministic. As a result, the exact code generated may vary, and there's even a chance it'll abide by our rules without us spelling it out! But to aid consistency in code we should always document anything we want to ensure Copilot should understand about how we want our code generated. ## Add global standards to copilot-instructions.md -As highlighted previously, **copilot-instructions.md** is designed to provide project-level information to Copilot. Let's ensure global coding standards are documented to improve code suggestions from Copilot chat. +As highlighted previously, `copilot-instructions.md` is designed to provide project-level information to Copilot. Let's ensure global coding standards are documented to improve code suggestions from Copilot chat. 1. Return to your codespace. -2. Open **.github/copilot-instructions.md**. +2. Open `.github/copilot-instructions.md`. 3. Explore the file, noting the brief description of the project and sections for **Code standards**, **Scripts** and **GitHub Actions Workflows**. These are applicable to any interactions we'd have with Copilot, are robust, and provide clear guidance on what we're doing and how we want to accomplish it. 4. Locate the **Code formatting requirements** section, which should be around line 16. Note how it contains a note to use type hints. That's why we saw those in the code generated previously. -5. Add the following lines of markdown right below the note about type hints to instruct Copilot to add comment headers to files and docstrings: +5. Add the following lines of markdown right below the note about type hints to instruct Copilot to add comment headers to files and docstrings (which should be near line 18): ```markdown - Every function should have docstrings or the language equivalent @@ -91,16 +87,13 @@ As highlighted previously, **copilot-instructions.md** is designed to provide pr 6. Close **copilot-instructions.md**. 7. Select **New Chat** in Copilot chat to clear the buffer and start a new conversation. 8. Return to **server/routes/publishers.py** to ensure focus is set correctly. -9. Send the same prompt as before to create the endpoint. +9. Send the same prompt as before to create the endpoint. ```plaintext Create a new endpoint to return a list of all publishers. It should return the name and id for all publishers. ``` -> [!TIP] -> You can cycle through previous prompts by using the up and down arrows on your keyboard. - -8. Notice how the newly generated code includes a comment header at the top of the file which resembles the following: +10. Notice how the newly generated code includes a comment header at the top of the file which resembles the following: ```python """ @@ -109,7 +102,7 @@ As highlighted previously, **copilot-instructions.md** is designed to provide pr """ ``` -9. Notice how the newly generated code includes a docstring inside the function which resembles the following: +11. Notice how the newly generated code includes a docstring inside the function which resembles the following: ```python """ @@ -120,9 +113,11 @@ As highlighted previously, **copilot-instructions.md** is designed to provide pr """ ``` -10. Also note how the existing code isn't updated, but of course we could ask Copilot to perform that operation if we so desired! +12. Also note how the existing code isn't updated, but of course we could ask Copilot to perform that operation if we so desired! +13. **Don't implement the suggested changes**, as we will be doing that in the next section. -11. **Don't implement the suggested changes**, as we will be doing that in the next section. +> [!NOTE] +> If you accepted the changes, you can always select the **Undo** button towards the top right of the Copilot chat window. From this section, you explored how the custom instructions file has provided Copilot with the context it needs to generate code that follows the established guidelines. @@ -132,21 +127,19 @@ Coding is often repetitive, with developers performing similar tasks on a regula We want to create a new endpoint to list all publishers, and to follow the same pattern we used for the existing [games endpoints][games-endpoints], and to create tests which follow the same pattern as the existing [games endpoints tests][games-tests]. An instruction file has already been created; let's explore it and see the difference in code it generates. -1. Open **.github/instructions/python-tests.instructions.md**. -2. Note the **applyTo:** section at the top, which contains a filter for all files in the **server/tests** directory which start with **test_** and have a **.py** extension. Whenever Copilot Chat interacts with a file which matches this pattern it will automatically use the guidance provided in this file. +1. Open `.github/instructions/python-tests.instructions.md`. +2. Note the `applyTo:` section at the top, which contains a filter for all files in the `server/tests` directory which start with `test_` and have a `.py` extension. Whenever Copilot Chat interacts with a file which matches this pattern it will automatically use the guidance provided in this file. 3. Note the file contains guidance about how tests should be created, and how to utilize SQLite when testing database functionality. -4. Open **.github/instructions/flask-endpoint.instructions.md**. +4. Open `.github/instructions/flask-endpoint.instructions.md`. 5. Review the following entries inside the instruction file, which includes: - an overview of requirements, including that tests must be created, and endpoints are created in Flask using blueprints. - - a link to another the previously mentioned **python-tests.instructions.md** file. + - a link to another the previously mentioned `python-tests.instructions.md` file. - links to two existing files which follow the patterns we want - both the games blueprint and tests. Notice how these are setup as normal markdown links, allowing an instruction file to incorporate additional files for context. -6. Return to **server/routes/publishers.py** to ensure focus is set correctly. +6. Return to `server/routes/publishers.py` to ensure focus is set correctly. 7. Return to Copilot Chat and select **New Chat** to start a new session. -8. Select **Edit** from the mode dropdown, which will allow Copilot to update multiple files. - - ![Screenshot of the Edit mode being highlighted in the Copilot Chat panel](images/copilot-edits.png) +8. Select **Edit** from the mode dropdown, which will allow Copilot to update multiple files. > [!NOTE] > If you have any issues running the tests in this part of the exercise, please undo your changes and retry from the above step using **Agent** mode instead. @@ -178,20 +171,25 @@ We want to create a new endpoint to list all publishers, and to follow the same > Note that the code generated may diverge from some of the standards we set. AI tools like Copilot are non-deterministic, and may not always provide the same result. The other files in our codebase do not contain docstrings or comment headers, which could lead Copilot in another direction. Consistency is key, so making sure that your code follows the established patterns is important. You can always follow-up in chat and ask Copilot to follow your coding standards, which will help guide it in the right direction. 16. After reviewing the code, select **Keep** in Copilot Chat to accept the changes. -17. Open a terminal window by selecting Ctl+\`. -18. Run the tests by running the script with the following command: +17. If you are prompted to run tests select **Cancel**; we'll perform this task later. +18. Open a terminal window by selecting Ctl + \`. +19. Run the tests by running the script with the following command: ```sh ./scripts/run-server-tests.sh ``` -19. Once the code is correct, and all tests pass, open the **Source Control** panel on the left of the Codespace and review the changes made by Copilot. -20. Stage the changes by selecting the **+** icon in the **Source Control** panel. -21. Generate a commit message using the **Sparkle** button. +20. Once the code is correct, and all tests pass, open the **Source Control** panel on the left of the Codespace and review the changes made by Copilot. + +> [!NOTE] +> If any tests fail, ask Copilot to suggest a fix. You can use `@terminal /explain` to give Copilot the context of your terminal window. + +21. Stage the changes by selecting the **+** icon in the **Source Control** panel. +22. Generate a commit message using the **Sparkle** button. ![Screenshot of the Source Control panel showing the changes made](images/source-control-changes.png) -22. Commit the changes to your repository by selecting **Commit**. +23. Commit the changes to your repository by selecting **Commit**. ## Summary and next steps diff --git a/docs/4-copilot-agent-mode-vscode.md b/docs/4-copilot-agent-mode-vscode.md index b3f5c2f..d718fda 100644 --- a/docs/4-copilot-agent-mode-vscode.md +++ b/docs/4-copilot-agent-mode-vscode.md @@ -7,7 +7,10 @@ Even the simplest of updates to an application typically require updates to mult This is where Copilot Agent Mode comes into play. -Copilot Agent Mode is built to act more autonomously. It behaves in a similar fashion to a developer, starting by exploring the existing project structure, performing the necessary updates, running tasks like tests, and automatically fixing any discovered mistakes. Let's explore how we can use Agent Mode to introduce new functionality to our site. +Copilot Agent Mode is built to act more autonomously in your IDE. It behaves in a similar fashion to a developer, starting by exploring the existing project structure, performing the necessary updates, running tasks like tests, and automatically fixing any discovered mistakes. Let's explore how we can use Agent Mode to introduce new functionality to our site. + +> [!NOTE] +> While the names are similar, agent mode and coding agent are built for two different types of experiences. Agent mode performs its tasks in your IDE, allowing for quick feedback cycles and interaction. Coding agent is designed as a peer programmer, working asynchronously like a member of the team, interacting with you via issues and pull requests. In this exercise, you will learn how: @@ -30,7 +33,7 @@ The website is a crowdfunding platform for board games with a developer theme. I To make running the website easier, we have provided a script that will start both the front-end and back-end servers. You can run this script in your GitHub Codespace to start the website with the following instructions: 1. Return to your codespace. We'll continue working in your current branch. -2. Open a new terminal window inside your codespace by selecting Ctl+\`. +2. Open a new terminal window inside your codespace by selecting Ctl + \`. 3. Run the following script to start the website: ```bash @@ -47,7 +50,7 @@ To make running the website easier, we have provided a script that will start bo > [!NOTE] > If a dialog box opens prompting you to open a browser window for http://localhost:5100 close it by selecting the **x**. -4. Open the website by using Ctrl-**Click** (or Cmd-**Click** on a Mac) on the client address (http://localhost:4321) in the terminal. +4. Open the website by using Ctrl-**Click** (or Cmd-**Click** on a Mac) on the client address `http://localhost:4321` in the terminal. > [!NOTE] > When using a codespace, selecting a link for the localhost URL from the Codespace terminal will automatically redirect you to `https://-4321.app.github.dev/`. This is a private tunnel to your codespace, which is now hosting your web server! @@ -67,21 +70,18 @@ The initial implementation of the website is functional, but we want to enhance 2. Open **Copilot Chat**. 3. Create a new chat session by selecting the **New Chat** button, which will remove any previous context. 4. Ensure **Agent** is selected from the list of modes. - - ![Screenshot of the Copilot Chat panel showing the Agent Mode dropdown](images/copilot-agent-mode-dropdown.png) - -5. Select **Claude 3.5 Sonnet** from the list of available models. +5. Select **Claude Sonnet 4** from the list of available models. > [!IMPORTANT] -> The authors of this lab are not indicating a preference towards one model or another. When building this lab, we used Claude 3.5, and as such are including that in the instructions. The hope is the code suggestions you receive will be relatively consistent to ensure a good experience. However, because LLMs are probabilistic, you may notice the suggestions received differ from what is indicated in the lab. This is perfectly normal and expected. +> The authors of this lab are not indicating a preference towards one model or another. When building this lab, we used Claude Sonnet 4, and as such are including that in the instructions. The hope is the code suggestions you receive will be relatively consistent to ensure a good experience. However, because LLMs are probabilistic, you may notice the suggestions received differ from what is indicated in the lab. This is perfectly normal and expected. -5. Ask Copilot about the backlog of issues by sending the following prompt to Copilot, replacing **** with the organization/name of your repository which you noted earlier: +1. Ask Copilot about the backlog of issues by sending the following prompt to Copilot: ```plaintext - Please show me the backlog of items from my repository at . Help me prioritize them based on those which will be most useful to the user. + Please show me the backlog of items from my GitHub repository. Help me prioritize them based on those which will be most useful to the user. ``` -6. Notice GitHub Copilot (likely) identifies **list_issues** as the MCP command to run to access the right information. +2. Notice GitHub Copilot (likely) identifies `list_issues` or `search_issues` as the MCP command to run to access the right information. > [!NOTE] > Because of the probabilistic nature of LLMs, Copilot may utilize a different MCP command, but should still be able to complete the task. @@ -110,14 +110,11 @@ In addition, the tests need to run (and pass) before we merge everything into ou > Even though Copilot agent mode may have discovered this file on its own, if you're aware of an important piece of information, like a **.instructions.md** file, then absolutely add it to Copilot's context. This helps set Copilot (and you) up for success. 3. Ensure **Agent** mode is still selected. - - ![Screenshot showing an example of switching to Agent Mode](images/copilot-agent-mode-dropdown.png) - -4. Ensure **Claude 3.5** is still selected for the model. -5. Prompt Copilot to implement the functionality based on the issue we created earlier by using the following prompt, replacing **** with the organization/name of your repository which you noted earlier: +4. Ensure **Claude Sonnet 4** is still selected for the model. +5. Prompt Copilot to implement the functionality based on the issue we created earlier by using the following prompt: ```plaintext - Please update the site to include filtering by publisher and category based on the requirements from the related GitHub issue in the backlog of . + Please update the site to include filtering by publisher and category based on the requirements from the related GitHub issue in the backlog. The server is already running, so you do not need to start it up. ``` 6. Watch as Copilot begins by exploring the project, locating the files associated with the desired functionality. You should see it finding both the API and UI definitions, as well as the tests. It then begins modifying the files and running the tests. @@ -160,10 +157,10 @@ With our changes created locally we're ready to create a pull request (PR) to al There are several ways to create a pull request, including through github.com and the GitHub command-line interface (CLI). But since we're already working with GitHub Copilot, let's let it create the PR for us! We can have it find the relevant issue and create the PR with an association to the located issue. 1. Navigate to the Copilot Chat panel and select **New Chat** to start a new session. -2. Ask Copilot to create a PR for you, replacing **** with the organization/name of your repository which you noted earlier: +2. Ask Copilot to create a PR for you: ```plaintext - Find the issue related to filtering by category and publisher on . Create a new pull request for the current add-filters branch, and associate it with the correct issue. + Find the issue in the repo related to filtering by category and publisher. Create a new pull request for the current add-filters branch, and associate it with the correct issue. ``` 3. As needed, select **Continue** to allow Copilot to perform the tasks necessary to gather information and perform operations. diff --git a/docs/5-reviewing-coding-agent.md b/docs/5-reviewing-coding-agent.md index bcb743a..d0e747b 100644 --- a/docs/5-reviewing-coding-agent.md +++ b/docs/5-reviewing-coding-agent.md @@ -47,21 +47,20 @@ Let's start by exploring the first pull request (PR) generated by GitHub Copilot ## Requesting changes from GitHub Copilot -Working with Copilot on a pull request is not just a one-way street. You can also add comments to the pull request, or inline comments to the code. Copilot will see these comments, and trigger another session to address them. Due to the non-deterministic results, we can't give prescriptive text of what to ask for. Some ideas of what to ask Copilot to update include: +Working with Copilot on a pull request is not just a one-way street. You can also tag Copilot in comments - like you would other members of your team - in the pull request, or inline comments of the code. Copilot will see these comments, and trigger another session to address them. Due to the non-deterministic results, we can't give prescriptive text of what to ask for. Some ideas of what to ask Copilot to update include: - Add comment headers to the top of each code file with a brief description of what they do. - Add docstrings to TypeScript and Svelte files. - Create a README in both the server and client folders with descriptions of the codebase of each. -1. Add a comment requesting a change to the generated documentation. Use one of the ideas above, or another suggestion for Copilot around documentation you'd like to see in the codebase. -2. Feel free to watch the session as Copilot works on the changes. -3. Select **View Session** to watch Copilot perform its work. Notice how Copilot starts a new session to make the updates. -4. You can select **Back to pull request** to return to the pull request. +1. Add a comment requesting a change to the generated documentation, tagging **@copilot** like you would any user. Use one of the ideas above, or another suggestion for Copilot around documentation you'd like to see in the codebase. +2. Select **View Session** to watch Copilot perform its work. Notice how Copilot starts a new session to make the updates. +3. You can select **Back to pull request** to return to the pull request. ![Back to pull request](images/ex4-back-to-pr.png) -5. Once Copilot has completed the changes, you should see a new commit in the pull request. -6. Select the **Files changed** tab to review the changes. +4. Once Copilot has completed the changes, you should see a new commit in the pull request. +5. Select the **Files changed** tab to review the changes. Feel free to continue iterating until you are happy. Once happy, you can convert the PR to ready from a draft, and merge it into the main branch. diff --git a/docs/images/codespace-startup.png b/docs/images/codespace-startup.png deleted file mode 100644 index 559eb96..0000000 Binary files a/docs/images/codespace-startup.png and /dev/null differ diff --git a/docs/images/copilot-add-instructions-file.png b/docs/images/copilot-add-instructions-file.png index 9eff427..6ff042b 100644 Binary files a/docs/images/copilot-add-instructions-file.png and b/docs/images/copilot-add-instructions-file.png differ diff --git a/docs/images/copilot-agent-mode-mcp-tools.png b/docs/images/copilot-agent-mode-mcp-tools.png deleted file mode 100644 index 0429484..0000000 Binary files a/docs/images/copilot-agent-mode-mcp-tools.png and /dev/null differ diff --git a/docs/images/copilot-agent-mode-model.png b/docs/images/copilot-agent-mode-model.png index fe99d03..086a87c 100644 Binary files a/docs/images/copilot-agent-mode-model.png and b/docs/images/copilot-agent-mode-model.png differ diff --git a/docs/images/copilot-agent-mode.png b/docs/images/copilot-agent-mode.png deleted file mode 100644 index 4055a48..0000000 Binary files a/docs/images/copilot-agent-mode.png and /dev/null differ diff --git a/docs/images/copilot-chat-ask.png b/docs/images/copilot-chat-ask.png deleted file mode 100644 index 9203359..0000000 Binary files a/docs/images/copilot-chat-ask.png and /dev/null differ diff --git a/docs/images/copilot-chat-dropdown.png b/docs/images/copilot-chat-dropdown.png deleted file mode 100644 index 36369dd..0000000 Binary files a/docs/images/copilot-chat-dropdown.png and /dev/null differ diff --git a/docs/images/copilot-chat-window.png b/docs/images/copilot-chat-window.png deleted file mode 100644 index 0f58e7d..0000000 Binary files a/docs/images/copilot-chat-window.png and /dev/null differ diff --git a/docs/images/copilot-edits.png b/docs/images/copilot-edits.png deleted file mode 100644 index a82e7ec..0000000 Binary files a/docs/images/copilot-edits.png and /dev/null differ diff --git a/docs/images/copilot-new-chat.png b/docs/images/copilot-new-chat.png deleted file mode 100644 index ada8590..0000000 Binary files a/docs/images/copilot-new-chat.png and /dev/null differ diff --git a/docs/images/dotnet-finished.png b/docs/images/dotnet-finished.png deleted file mode 100644 index a6d2707..0000000 Binary files a/docs/images/dotnet-finished.png and /dev/null differ diff --git a/docs/images/ex2-mcp-server-started.png b/docs/images/ex2-mcp-server-started.png deleted file mode 100644 index bdf3149..0000000 Binary files a/docs/images/ex2-mcp-server-started.png and /dev/null differ diff --git a/docs/images/ex4-conversation-tab.png b/docs/images/ex4-conversation-tab.png deleted file mode 100644 index 0ac54d4..0000000 Binary files a/docs/images/ex4-conversation-tab.png and /dev/null differ diff --git a/docs/images/ex4-copilot-session.png b/docs/images/ex4-copilot-session.png deleted file mode 100644 index 8f6dcff..0000000 Binary files a/docs/images/ex4-copilot-session.png and /dev/null differ diff --git a/docs/images/ex4-files-changed-session1.png b/docs/images/ex4-files-changed-session1.png deleted file mode 100644 index df6c378..0000000 Binary files a/docs/images/ex4-files-changed-session1.png and /dev/null differ diff --git a/docs/images/ex4-files-changed-session2.png b/docs/images/ex4-files-changed-session2.png deleted file mode 100644 index 8f7ce6d..0000000 Binary files a/docs/images/ex4-files-changed-session2.png and /dev/null differ diff --git a/docs/images/ex4-new-pr-comment.png b/docs/images/ex4-new-pr-comment.png deleted file mode 100644 index 4cbce41..0000000 Binary files a/docs/images/ex4-new-pr-comment.png and /dev/null differ diff --git a/docs/images/ex4-pr-comment-eyes.png b/docs/images/ex4-pr-comment-eyes.png deleted file mode 100644 index aba7de8..0000000 Binary files a/docs/images/ex4-pr-comment-eyes.png and /dev/null differ diff --git a/docs/images/ex4-session2-pr-comment.png b/docs/images/ex4-session2-pr-comment.png deleted file mode 100644 index e27be60..0000000 Binary files a/docs/images/ex4-session2-pr-comment.png and /dev/null differ