From 5e998df3ea139afc495592d6b52f260b5e823352 Mon Sep 17 00:00:00 2001 From: Zack Way Date: Wed, 6 Aug 2025 10:46:21 -0400 Subject: [PATCH 1/6] Refactor documentation for spec-driven development; update project brief references and remove obsolete files --- README.md | 6 ++-- conportal-python.md | 54 -------------------------------- goals/dotnet/1-setup.md | 34 +++++++------------- goals/dotnet/projectBrief.md | 40 ----------------------- goals/java/1-setup.md | 33 +++++++------------ goals/java/projectBrief.md | 41 ------------------------ goals/python/1-setup.md | 33 +++++++------------ goals/python/projectBrief.md | 40 ----------------------- goals/typescript/1-setup.md | 34 +++++++------------- goals/typescript/projectBrief.md | 40 ----------------------- 10 files changed, 49 insertions(+), 306 deletions(-) delete mode 100644 conportal-python.md delete mode 100644 goals/dotnet/projectBrief.md delete mode 100644 goals/java/projectBrief.md delete mode 100644 goals/python/projectBrief.md delete mode 100644 goals/typescript/projectBrief.md diff --git a/README.md b/README.md index d2cbb92..828557a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# Scenario : Advanced AI Pair Programming Challenge +# Scenario : Spec Driven Development Programming Challenge -Developers today agree that AI code assistant tools are useful for easy, repeatable tasks. JSON to Class, quick templated code, writing simple scripts. But most still think it's bad at more complex tasks. This exercise is here to show you that assumption is no longer as true as you might think! +Developers today agree that AI code assistant tools are useful for easy, repeatable tasks. JSON to Class, quick templated code, writing simple scripts. But most still think it's bad at more complex tasks. This exercise is here to show you that assumption is no longer as true as you might think! Spec-driven development takes your skills as a Software Engineer and augments your AI Coding Assistant to build software *your* way. ## Prerequisites -- Clone the AI Assisted Coding Framework repository: https://github.com/ChrisMcKee1/AI-Assisted-Coding +- Clone the Spec Driven Coding Framework repository: https://github.com/seiggy/AI-Assisted-Coding - [Install & start Docker Desktop](https://docs.docker.com/get-started/get-docker/) or diff --git a/conportal-python.md b/conportal-python.md deleted file mode 100644 index 60b62ec..0000000 --- a/conportal-python.md +++ /dev/null @@ -1,54 +0,0 @@ -# Context Portal MCP in Python - -## Prerequisites - -Before you begin, ensure you have the following installed: - -- **Python:** Version 3.8 or higher is recommended. - - [Download Python](https://www.python.org/downloads/) - - Ensure Python is added to your system's PATH during installation (especially on Windows). -- **uv:** (Highly Recommended) A fast Python environment and package manager. Using `uv` significantly simplifies virtual environment creation and dependency installation. - - [Install uv](https://github.com/astral-sh/uv#installation) - -## Installation and Configuration - -The recommended way to install and run ConPort is by using `uvx` to execute the package directly from PyPI. This method avoids the need to manually create and manage virtual environments. - - -### `uvx` Configuration - -In the `mcp.json` file of your `.vscode` folder, change the conport configuration to the following: - -```json -{ - ... - "conport": { - "command": "uvx", - "type": "stdio", - "args": [ - "--from", - "context-portal-mcp", - "conport-mcp", - "--mode", - "stdio", - "--workspace_id", - "${workspaceFolder}", - "--log-file", - "./logs/conport.log", - "--log-level", - "INFO" - ] - } - ... -} -``` - -- **`command`**: `uvx` handles the environment for you. -- **`args`**: Contains the arguments to run the ConPort server. -- `${workspaceFolder}`: This IDE variable is used to automatically provide the absolute path of the current project workspace. -- `--log-file`: Optional: Path to a file where server logs will be written. If not provided, logs are directed to `stderr` (console). Useful for persistent logging and debugging server behavior. -- `--log-level`: Optional: Sets the minimum logging level for the server. Valid choices are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. Defaults to `INFO`. Set to `DEBUG` for verbose output during development or troubleshooting. - -### Update the `copilot-instructions.md` - -Finally, you'll need to update the copilot instructions file. We currently hardcode the Workspace Id for ConPort to be `/app/workspace` as that is the workspace we use within the Docker container to connect to your code. Since you are running the code locally, you will need to change this to `${workspaceFolder}`. So do a find-replace of `/app/workspace` and replace with `${workspaceFolder}`. This should allow VS Code to automatically send the correct workspace ID to your ConPort process. \ No newline at end of file diff --git a/goals/dotnet/1-setup.md b/goals/dotnet/1-setup.md index 7c2a3f3..b5687ed 100644 --- a/goals/dotnet/1-setup.md +++ b/goals/dotnet/1-setup.md @@ -3,14 +3,13 @@ This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references -- **ConPort MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites -- **Docker** or **Podman** (for ConPort MCP) -- **Node.js 16+** (for Context7 MCP server) - Optional, see step 2 below +- **Node.js 16+** (for MCP tools) - **VS Code** with GitHub Copilot extension - **Git** for version control @@ -40,15 +39,15 @@ rsync -av --exclude='.git' . /path/to/your-project/ ### Step 2 (optional): Change the MCP Configuration -By default, we utilize the local Contex7 MCP server for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize iether the public Context7 MCP server, or build and run the Docker version of the Context7 MCP tool. The `.vscode/mcp.json` file has commented out configuration options for these two paths. +By default, we utilize the local MCP tools for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize docker versions of each tool. To build and run the Docker version of the the tools, you will need to see the documentation for each to setup the docker config: See the [Context7 Docker Readme](../../context7-docker.md) for instructions on how to use Docker to host Context7 locally. -Also, we are using Docker for hosting the Context Portal MCP server. We recommend you pull the image locally before you start up VS Code. To pull the image: +See the [Playwright MCP Readme](https://github.com/microsoft/playwright-mcp) for details on advanced configuration and docker support for Playwright. -`docker pull seiggy/context-portal-mcp:0.2.18` +See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking) for details on how to configure it using docker. -If you are using Podman, replace `docker` with `podman` in both the command, and in the `mcp.json` file. If you do not have Docker installed, you can run the Context Portal MCP server locally using Python and UV. For further details on how to use the ConPort MCP server with Python, see the [Context Portal Python Readme](../../conportal-python.md). +See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker ### Step 3: Open Project in VS Code @@ -56,28 +55,19 @@ If you are using Podman, replace `docker` with `podman` in both the command, and # Open your project in VS Code code . ``` -### Step 4: Update Your Project Brief -Before proceeding, overwrite the `projectBrief.md` in your project root that you copied from the AI-Assisted-Coding repository, with the `projectBrief.md` file we provided in this repository. +### Step 4: Run the Analyze Workflow + +Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. ### Step 5: Verify GitHub Copilot Integration 1. Ensure GitHub Copilot extension is installed and activated -2. The framework will automatically detect the `copilot-instructions.md` file - - -### Step 6: Initialize ConPort MCP - -After verifying Copilot integration, initialize the ConPort MCP memory system: +2. The framework will automatically generate the `copilot-instructions.md` file +3. The framework should also generate a series of files in a folder named `.docs` -1. In the Copilot chat or comments, type: - ``` - Initialize ConPort - ``` -1. Follow the prompts to complete setup. - This step creates the persistent memory database and loads your project context before you start coding. -### Step 7: Have the AI conduct Architecture Review +### Step 8: Have the AI conduct Architecture Review Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! diff --git a/goals/dotnet/projectBrief.md b/goals/dotnet/projectBrief.md deleted file mode 100644 index 74b321c..0000000 --- a/goals/dotnet/projectBrief.md +++ /dev/null @@ -1,40 +0,0 @@ -# Project Brief: eShop (.NET Reference Application) - -## Overview -The **eShop** project is a reference .NET application developed by the .NET team to demonstrate modern application architecture and development practices using the latest .NET technologies. It implements a full-featured e-commerce website and serves as a practical example for developers building cloud-native, scalable, and maintainable applications. - -## Purpose -The primary goals of the eShop project are to: -- Showcase best practices in .NET application development. -- Demonstrate the use of **.NET Aspire**, a new stack for building distributed applications. -- Provide a hands-on learning tool for developers exploring microservices, containerization, and modern frontend/backend integration. - -## Key Features -- **Architecture**: Services-based architecture using .NET Aspire. -- **Frontend**: Built with Blazor WebAssembly and ASP.NET Core. -- **Backend**: Includes APIs, microservices, and integration with databases and messaging systems. -- **DevOps Ready**: Includes CI/CD pipelines and Docker support. -- **AI Integration**: Features an AI-powered chatbot to assist users in product discovery and shopping. -- **Performance Optimizations**: - - Uses `MapStaticAssets` for optimized static file handling. - - Implements Brotli compression and fingerprinted file names for aggressive caching. - -## Technology Stack -- .NET 9 (latest version) -- ASP.NET Core -- Blazor -- Docker -- Visual Studio 2022+ -- Optional: .NET MAUI for cross-platform client apps - -## Getting Started -To run the eShop project: -1. Clone the repository: [github.com/dotnet/eshop](https://github.com/dotnet/eshop) -2. Install prerequisites: - - .NET 9 SDK - - Visual Studio 2022 (with ASP.NET and .NET Aspire workloads) - - Docker Desktop -3. Run the solution using Visual Studio or configure your environment using the provided PowerShell scripts. - -## Internal Use and Demonstrations -The eShop app has been featured in internal presentations such as the [dotnet conf 2024 Keynote - Copy 3](https://microsoft.sharepoint.com/teams/DevRelTeam/_layouts/15/Doc.aspx?sourcedoc=%7B15D653EE-CFB6-4C32-8669-EF8B2367FE95%7D&file=dotnet%20conf%202024%20Keynote%20-%20Copy%203.pptx&action=edit&mobileredirect=true&DefaultItemOpen=1&EntityRepresentationId=421e3d07-d5fd-4cc9-b4ee-9dac667e0f4b), where it was used to demonstrate .NET 9 \ No newline at end of file diff --git a/goals/java/1-setup.md b/goals/java/1-setup.md index 7c2a3f3..4154c02 100644 --- a/goals/java/1-setup.md +++ b/goals/java/1-setup.md @@ -3,14 +3,13 @@ This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references -- **ConPort MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites -- **Docker** or **Podman** (for ConPort MCP) -- **Node.js 16+** (for Context7 MCP server) - Optional, see step 2 below +- **Node.js 16+** (for MCP tools) - **VS Code** with GitHub Copilot extension - **Git** for version control @@ -40,15 +39,15 @@ rsync -av --exclude='.git' . /path/to/your-project/ ### Step 2 (optional): Change the MCP Configuration -By default, we utilize the local Contex7 MCP server for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize iether the public Context7 MCP server, or build and run the Docker version of the Context7 MCP tool. The `.vscode/mcp.json` file has commented out configuration options for these two paths. +By default, we utilize the local MCP tools for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize docker versions of each tool. To build and run the Docker version of the the tools, you will need to see the documentation for each to setup the docker config: See the [Context7 Docker Readme](../../context7-docker.md) for instructions on how to use Docker to host Context7 locally. -Also, we are using Docker for hosting the Context Portal MCP server. We recommend you pull the image locally before you start up VS Code. To pull the image: +See the [Playwright MCP Readme](https://github.com/microsoft/playwright-mcp) for details on advanced configuration and docker support for Playwright. -`docker pull seiggy/context-portal-mcp:0.2.18` +See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking) for details on how to configure it using docker. -If you are using Podman, replace `docker` with `podman` in both the command, and in the `mcp.json` file. If you do not have Docker installed, you can run the Context Portal MCP server locally using Python and UV. For further details on how to use the ConPort MCP server with Python, see the [Context Portal Python Readme](../../conportal-python.md). +See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker ### Step 3: Open Project in VS Code @@ -56,28 +55,18 @@ If you are using Podman, replace `docker` with `podman` in both the command, and # Open your project in VS Code code . ``` -### Step 4: Update Your Project Brief +### Step 4: Run the Analyze Workflow -Before proceeding, overwrite the `projectBrief.md` in your project root that you copied from the AI-Assisted-Coding repository, with the `projectBrief.md` file we provided in this repository. +Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. ### Step 5: Verify GitHub Copilot Integration 1. Ensure GitHub Copilot extension is installed and activated -2. The framework will automatically detect the `copilot-instructions.md` file +2. The framework will automatically generate the `copilot-instructions.md` file +3. The framework should also generate a series of files in a folder named `.docs` -### Step 6: Initialize ConPort MCP - -After verifying Copilot integration, initialize the ConPort MCP memory system: - -1. In the Copilot chat or comments, type: - ``` - Initialize ConPort - ``` -1. Follow the prompts to complete setup. - This step creates the persistent memory database and loads your project context before you start coding. - -### Step 7: Have the AI conduct Architecture Review +### Step 8: Have the AI conduct Architecture Review Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! diff --git a/goals/java/projectBrief.md b/goals/java/projectBrief.md deleted file mode 100644 index e669361..0000000 --- a/goals/java/projectBrief.md +++ /dev/null @@ -1,41 +0,0 @@ -# Project Brief: Spring Petclinic Microservices - -## Overview -The **Spring Petclinic Microservices** project is a reference application based on the well-known Spring Petclinic sample, re-architected as a set of microservices. Developed and maintained by Azure Samples, it demonstrates how to build and deploy cloud-native Java applications on the Microsoft Azure platform. The application implements a full-featured veterinary clinic management system and serves as a practical example for developers. - -## Purpose -The primary goals of this project are to: -- Showcase best practices for building and deploying microservices with Spring Boot and Spring Cloud on Azure. -- Demonstrate the use of **Azure Spring Apps** for hosting scalable and resilient Java applications. -- Provide a hands-on learning tool for developers exploring microservices, Infrastructure as Code (IaC), and modern DevOps practices on Azure. -- Serve as an **Azure Developer CLI (`azd`)** template for rapid, repeatable environment provisioning and application deployment. - -## Key Features -- **Architecture**: A distributed microservices architecture using Spring Boot, including services for customers, vets, and visits, managed via a discovery server and an API gateway. -- **Frontend**: Built with AngularJS and Bootstrap, providing a dynamic user interface. -- **Backend**: A suite of microservices developed with Java and the Spring Framework. -- **DevOps Ready**: Includes CI/CD pipeline examples using GitHub Actions and Infrastructure as Code definitions with Bicep. -- **Cloud Integration**: Leverages key Azure services such as **Azure Spring Apps**, **Azure Database for MySQL**, and **Azure Key Vault** for comprehensive cloud-native capabilities. - -## Technology Stack -- Java 17+ -- Spring Boot & Spring Cloud -- AngularJS & Bootstrap -- Maven -- Docker -- Azure Spring Apps -- Azure Database for MySQL -- Azure Developer CLI (`azd`) -- Bicep - -## Getting Started -To run the Spring Petclinic project on Azure: -1. Clone the repository: `git clone https://github.com/Azure-Samples/spring-petclinic-microservices.git` -2. Install prerequisites: - - Azure Developer CLI (`azd`) - - Java 17 SDK - - Azure CLI -3. Run the solution on Azure using the `azd up` command, which handles provisioning and deployment. - -## Use as a Reference Sample -This application is used as a public reference sample in various Microsoft tutorials, learning modules, and documentation to demonstrate how to effectively build and deploy modern Java applications on Azure. \ No newline at end of file diff --git a/goals/python/1-setup.md b/goals/python/1-setup.md index 7c2a3f3..4154c02 100644 --- a/goals/python/1-setup.md +++ b/goals/python/1-setup.md @@ -3,14 +3,13 @@ This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references -- **ConPort MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites -- **Docker** or **Podman** (for ConPort MCP) -- **Node.js 16+** (for Context7 MCP server) - Optional, see step 2 below +- **Node.js 16+** (for MCP tools) - **VS Code** with GitHub Copilot extension - **Git** for version control @@ -40,15 +39,15 @@ rsync -av --exclude='.git' . /path/to/your-project/ ### Step 2 (optional): Change the MCP Configuration -By default, we utilize the local Contex7 MCP server for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize iether the public Context7 MCP server, or build and run the Docker version of the Context7 MCP tool. The `.vscode/mcp.json` file has commented out configuration options for these two paths. +By default, we utilize the local MCP tools for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize docker versions of each tool. To build and run the Docker version of the the tools, you will need to see the documentation for each to setup the docker config: See the [Context7 Docker Readme](../../context7-docker.md) for instructions on how to use Docker to host Context7 locally. -Also, we are using Docker for hosting the Context Portal MCP server. We recommend you pull the image locally before you start up VS Code. To pull the image: +See the [Playwright MCP Readme](https://github.com/microsoft/playwright-mcp) for details on advanced configuration and docker support for Playwright. -`docker pull seiggy/context-portal-mcp:0.2.18` +See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking) for details on how to configure it using docker. -If you are using Podman, replace `docker` with `podman` in both the command, and in the `mcp.json` file. If you do not have Docker installed, you can run the Context Portal MCP server locally using Python and UV. For further details on how to use the ConPort MCP server with Python, see the [Context Portal Python Readme](../../conportal-python.md). +See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker ### Step 3: Open Project in VS Code @@ -56,28 +55,18 @@ If you are using Podman, replace `docker` with `podman` in both the command, and # Open your project in VS Code code . ``` -### Step 4: Update Your Project Brief +### Step 4: Run the Analyze Workflow -Before proceeding, overwrite the `projectBrief.md` in your project root that you copied from the AI-Assisted-Coding repository, with the `projectBrief.md` file we provided in this repository. +Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. ### Step 5: Verify GitHub Copilot Integration 1. Ensure GitHub Copilot extension is installed and activated -2. The framework will automatically detect the `copilot-instructions.md` file +2. The framework will automatically generate the `copilot-instructions.md` file +3. The framework should also generate a series of files in a folder named `.docs` -### Step 6: Initialize ConPort MCP - -After verifying Copilot integration, initialize the ConPort MCP memory system: - -1. In the Copilot chat or comments, type: - ``` - Initialize ConPort - ``` -1. Follow the prompts to complete setup. - This step creates the persistent memory database and loads your project context before you start coding. - -### Step 7: Have the AI conduct Architecture Review +### Step 8: Have the AI conduct Architecture Review Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! diff --git a/goals/python/projectBrief.md b/goals/python/projectBrief.md deleted file mode 100644 index 9d1e892..0000000 --- a/goals/python/projectBrief.md +++ /dev/null @@ -1,40 +0,0 @@ -# Project Brief: eShop (.NET Reference Application) - -## Overview -The **eShop** project is a reference .NET application developed by the .NET team to demonstrate modern application architecture and development practices using the latest .NET technologies. It implements a full-featured e-commerce website and serves as a practical example for developers building cloud-native, scalable, and maintainable applications. - -## Purpose -The primary goals of the eShop project are to: -- Showcase best practices in .NET application development. -- Demonstrate the use of **.NET Aspire**, a new stack for building distributed applications. -- Provide a hands-on learning tool for developers exploring microservices, containerization, and modern frontend/backend integration. - -## Key Features -- **Architecture**: Services-based architecture using .NET Aspire. -- **Frontend**: Built with Blazor WebAssembly and ASP.NET Core. -- **Backend**: Includes APIs, microservices, and integration with databases and messaging systems. -- **DevOps Ready**: Includes CI/CD pipelines and Docker support. -- **AI Integration**: Features an AI-powered chatbot to assist users in product discovery and shopping. -- **Performance Optimizations**: - - Uses `MapStaticAssets` for optimized static file handling. - - Implements Brotli compression and fingerprinted file names for aggressive caching. - -## Technology Stack -- .NET 9 (latest version) -- ASP.NET Core -- Blazor -- Docker -- Visual Studio 2022+ -- Optional: .NET MAUI for cross-platform client apps - -## Getting Started -To run the eShop project: -1. Clone the repository: [github.com/dotnet/eshop](https://github.com/dotnet/eshop) -2. Install prerequisites: - - .NET 9 SDK - - Visual Studio 2022 (with ASP.NET and .NET Aspire workloads) - - Docker Desktop -3. Run the solution using Visual Studio or configure your environment using the provided PowerShell scripts. - -## Internal Use and Demonstrations -The eShop app has been featured in internal presentations such as the `[dotnet conf 2024 Keynote - Copy 3](https://microsoft.sharepoint.com/teams/DevRelTeam/_layouts/15/Doc.aspx?sourcedoc=%7B15D653EE-CFB6-4C32-8669-EF8B2367FE95%7D&file=dotnet%20conf%202024%20Keynote%20-%20Copy%203.pptx&action=edit&mobileredirect=true&DefaultItemOpen=1&EntityRepresentationId=421e3d07-d5fd-4cc9-b4ee-9dac667e0f4b)`, where it was used to demonstrate .NET 9 \ No newline at end of file diff --git a/goals/typescript/1-setup.md b/goals/typescript/1-setup.md index 7c2a3f3..b5687ed 100644 --- a/goals/typescript/1-setup.md +++ b/goals/typescript/1-setup.md @@ -3,14 +3,13 @@ This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references -- **ConPort MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites -- **Docker** or **Podman** (for ConPort MCP) -- **Node.js 16+** (for Context7 MCP server) - Optional, see step 2 below +- **Node.js 16+** (for MCP tools) - **VS Code** with GitHub Copilot extension - **Git** for version control @@ -40,15 +39,15 @@ rsync -av --exclude='.git' . /path/to/your-project/ ### Step 2 (optional): Change the MCP Configuration -By default, we utilize the local Contex7 MCP server for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize iether the public Context7 MCP server, or build and run the Docker version of the Context7 MCP tool. The `.vscode/mcp.json` file has commented out configuration options for these two paths. +By default, we utilize the local MCP tools for caching and speed. However, if you don't have NodeJS installed, and do not wish to use NodeJS, you can instead utilize docker versions of each tool. To build and run the Docker version of the the tools, you will need to see the documentation for each to setup the docker config: See the [Context7 Docker Readme](../../context7-docker.md) for instructions on how to use Docker to host Context7 locally. -Also, we are using Docker for hosting the Context Portal MCP server. We recommend you pull the image locally before you start up VS Code. To pull the image: +See the [Playwright MCP Readme](https://github.com/microsoft/playwright-mcp) for details on advanced configuration and docker support for Playwright. -`docker pull seiggy/context-portal-mcp:0.2.18` +See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking) for details on how to configure it using docker. -If you are using Podman, replace `docker` with `podman` in both the command, and in the `mcp.json` file. If you do not have Docker installed, you can run the Context Portal MCP server locally using Python and UV. For further details on how to use the ConPort MCP server with Python, see the [Context Portal Python Readme](../../conportal-python.md). +See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker ### Step 3: Open Project in VS Code @@ -56,28 +55,19 @@ If you are using Podman, replace `docker` with `podman` in both the command, and # Open your project in VS Code code . ``` -### Step 4: Update Your Project Brief -Before proceeding, overwrite the `projectBrief.md` in your project root that you copied from the AI-Assisted-Coding repository, with the `projectBrief.md` file we provided in this repository. +### Step 4: Run the Analyze Workflow + +Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. ### Step 5: Verify GitHub Copilot Integration 1. Ensure GitHub Copilot extension is installed and activated -2. The framework will automatically detect the `copilot-instructions.md` file - - -### Step 6: Initialize ConPort MCP - -After verifying Copilot integration, initialize the ConPort MCP memory system: +2. The framework will automatically generate the `copilot-instructions.md` file +3. The framework should also generate a series of files in a folder named `.docs` -1. In the Copilot chat or comments, type: - ``` - Initialize ConPort - ``` -1. Follow the prompts to complete setup. - This step creates the persistent memory database and loads your project context before you start coding. -### Step 7: Have the AI conduct Architecture Review +### Step 8: Have the AI conduct Architecture Review Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! diff --git a/goals/typescript/projectBrief.md b/goals/typescript/projectBrief.md deleted file mode 100644 index 0fd51e2..0000000 --- a/goals/typescript/projectBrief.md +++ /dev/null @@ -1,40 +0,0 @@ -# Project Brief: ngLibrary (Angular Reference Application) - -## Overview -The **ngLibrary** project is a reference Angular application that demonstrates modern web application architecture and development practices. It implements a full-featured e-commerce website for a bookstore and serves as a practical example for developers building scalable and maintainable applications with Angular. - -## Purpose -The primary goals of the ngLibrary project are to: -- Showcase best practices in Angular application development. -- Demonstrate the use of **NgRx** for state management in a real-world application. -- Provide a hands-on learning tool for developers exploring reactive programming, component-based architecture, and comprehensive testing strategies. - -## Key Features -- **Architecture**: Feature-based, reactive architecture using NgRx for state management. It follows a clear separation of concerns with smart (container) and UI (presentational) components. -- **Frontend**: Built with **Angular 11** and TypeScript. -- **Backend Integration**: Fetches book data from the public **Open Library API**. -- **Comprehensive Testing**: Includes unit tests with **Jest** and end-to-end tests with **Cypress**. -- **Component-Driven Development**: Uses **Storybook** to develop and showcase UI components in isolation. -- **Performance Optimizations**: - - Implements **lazy loading** for feature modules to improve initial load time. - - Uses `PreloadAllModules` strategy to preload lazy-loaded modules in the background. - -## Technology Stack -- Angular 11 -- NgRx (for state management) -- RxJS -- TypeScript -- Jest (for unit testing) -- Cypress (for end-to-end testing) -- Storybook (for UI component development) - -## Getting Started -To run the ngLibrary project: -1. Clone the repository: `git clone https://github.com/mrWh1te/ngLibrary.git` -2. Install prerequisites: - - Node.js - - Angular CLI -3. Install dependencies: `npm install` -4. Run the development server: `npm start` -5. To run tests: `npm test` -6. To view components in Storybook: `npm run storybook` \ No newline at end of file From 27e386b5ee35a9eda214916118cc279843ecdaca Mon Sep 17 00:00:00 2001 From: Zachary Way Date: Wed, 6 Aug 2025 10:48:29 -0400 Subject: [PATCH 2/6] Update goals/python/1-setup.md spelling fix Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- goals/python/1-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goals/python/1-setup.md b/goals/python/1-setup.md index 4154c02..68108f4 100644 --- a/goals/python/1-setup.md +++ b/goals/python/1-setup.md @@ -57,7 +57,7 @@ code . ``` ### Step 4: Run the Analyze Workflow -Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. +Run the `/analyze-product` prompt to analyze your workspace and generate the documents that help the spec-driven development workflow operate smoothly. ### Step 5: Verify GitHub Copilot Integration From b78a043164a2942e310c4fc5f369cdcde8d3c8a9 Mon Sep 17 00:00:00 2001 From: Zachary Way Date: Wed, 6 Aug 2025 10:48:50 -0400 Subject: [PATCH 3/6] Update goals/typescript/1-setup.md spelling fix Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- goals/typescript/1-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/goals/typescript/1-setup.md b/goals/typescript/1-setup.md index b5687ed..bca44f6 100644 --- a/goals/typescript/1-setup.md +++ b/goals/typescript/1-setup.md @@ -58,7 +58,7 @@ code . ### Step 4: Run the Analyze Workflow -Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. +Run the `/analyze-product` prompt to analyze your workspace and generate the documents that help the spec-driven development workflow operate smoothly. ### Step 5: Verify GitHub Copilot Integration From 81f7ceb2043f6e9ac35ae557442e8cb593112026 Mon Sep 17 00:00:00 2001 From: Zack Way Date: Thu, 28 Aug 2025 13:12:01 -0400 Subject: [PATCH 4/6] Refactor code structure for improved readability and maintainability --- goals/3-tips.md | 8 +- goals/dotnet/1-setup.md | 77 +++++++---- goals/dotnet/2-requirements.md | 176 +++---------------------- goals/java/1-setup.md | 64 ++++++---- goals/java/2-requirements.md | 198 ++++------------------------- goals/python/1-setup.md | 63 +++++---- goals/python/2-requirements.md | 176 +++---------------------- goals/typescript/1-setup.md | 62 +++++---- goals/typescript/2-requirements.md | 176 +++---------------------- requirements-template.md | 146 +++++++++++++++++++++ screenshots/rider_context_menu.png | Bin 0 -> 59370 bytes 11 files changed, 380 insertions(+), 766 deletions(-) create mode 100644 requirements-template.md create mode 100644 screenshots/rider_context_menu.png diff --git a/goals/3-tips.md b/goals/3-tips.md index 3fb6a2a..705f35d 100644 --- a/goals/3-tips.md +++ b/goals/3-tips.md @@ -16,11 +16,11 @@ ## Workflow-Specific Tips for This Framework - **Start with Requirements in Markdown** - Before using the `Plan` or `Act` commands, write detailed requirements and architectural notes in markdown files (e.g., `projectBrief.md`, `docs/`). This gives Copilot and the AI agent the context needed for accurate planning and implementation. + Before using the `/create-spec` or `/execute-tasks` commands, write detailed requirements and architectural notes in markdown files (e.g., `projectBrief.md`, `docs/`). This gives Copilot and the AI agent the context needed for accurate planning and implementation. - **Follow the Core Workflow Commands** - Use the provided commands (`Plan`, `Act`, `Research`, etc.) as described in the README to trigger structured workflows. This ensures Copilot leverages both live documentation and persistent project memory. -- **Sync ConPort Regularly** - After major changes or at the end of a session, run the `conport_sync_routine` to persist new knowledge, decisions, and context. This keeps the AI's memory up to date and prevents context loss. + Use the provided commands (`/create-spec`, `/execute-tasks`, `/browser-test`, etc.) as described in the README to trigger structured workflows. This ensures Copilot leverages both live documentation and persistent project memory. +- **Sync Regularly** + After major changes or at the end of a session, run the `/generate-report` to persist new knowledge, decisions, and context. This keeps the AI's memory up to date and prevents context loss. - **Document Decisions and Patterns** When you make architectural or implementation decisions, log them using the appropriate workflow or markdown files. This helps Copilot and the agent avoid repeating past mistakes and improves future suggestions. - **Use Semantic Search for Context** diff --git a/goals/dotnet/1-setup.md b/goals/dotnet/1-setup.md index b5687ed..c9f0e8a 100644 --- a/goals/dotnet/1-setup.md +++ b/goals/dotnet/1-setup.md @@ -1,41 +1,33 @@ ## πŸš€ Setting up the AI Assisted Coding Framework in your project -This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: +This framework integrates several powerful MCP (Model Context Protocol) tools to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references - **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Sequential Thinking MCP**: Assists the LLM with ordering tasks, and breaking down complex ideas +- **Microsoft.Learn MCP**: Give your LLM access to the entire Microsoft Learn knowledgebase! Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites - **Node.js 16+** (for MCP tools) -- **VS Code** with GitHub Copilot extension +- **Container Platform** An OCI compliant container runtime, such as: + - [Docker Desktop](https://www.docker.com/products/docker-desktop) + - [Podman](https://podman.io/) [^1] +- **IDE** with GitHub Copilot[^2] - **Git** for version control ## πŸ› οΈ Installation & Setup -### Step 1: Clone and Copy Framework Files +### Step 1: Clone The Framework Repository #### Windows Terminal: ```powershell # Clone this repository git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace 'your-project-path' with the actual path to your project -robocopy . "C:\path\to\your-project" /E /XD .git ``` -#### Linux / OSX Terminal: -```bash -git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace '/path/to/your-project' with the actual path to your project -rsync -av --exclude='.git' . /path/to/your-project/ -``` +We will use the files in this repository once you've setup your local workspace. Keep them somewhere easy to access, we recommend a folder such as `C:\github\` or `~/github` on Linux & OSX. ### Step 2 (optional): Change the MCP Configuration @@ -49,28 +41,59 @@ See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker -### Step 3: Open Project in VS Code +> [!IMPORTANT] +> If you intend to do this, please do this before coming to the workshop, and ensure they are setup and configured. This can take time to setup and troubleshoot, so be prepared. Our recommendation is to use the NodeJS versions of the tools. + +### Step 3: Clone the eShop Repository + +You'll be building this challenge using the popular eShop demo repository from Microsoft. Clone the [eShop](https://github.com/dotnet/eShop/) Repository from the dotnet team to an easy to access location on your machine. + +### Step 4: Copy the Framework to the eShop repository + +Copy the `.github` and `.vscode` folders from the AI-Assisted-Coding repository to the root of your eShop repository. An example script below assumes you cloned both repositories to the root of `C:\github` or `~/github` respectively. +#### Powershell ```powershell -# Open your project in VS Code -code . +cd c:\github\AI-Assisted-Coding +robocopy . "C:\github\eShop" /E /XD .git ``` -### Step 4: Run the Analyze Workflow +#### Bash +```bash +cd ~/github +rsync -av --exclude='.git' . ~/github/eShop +``` + + +### Step 5: Run the Analyze Workflow + +Open the eShop Solution using VS Code or your preferrred IDE. -Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. +Run the `/analyze-product` prompt in Copilot Agent Mode to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. -### Step 5: Verify GitHub Copilot Integration +> [!NOTE] +> If you are using Visual Studio 2022, you will need to manually reference custom instruction files. You will need to swap to "folder view" in Visual Studio 2022, and then you can type `#analyze-product.instructions.md` to find and reference the file in the chat window. -1. Ensure GitHub Copilot extension is installed and activated +> [!NOTE] +> If you are using Jebrains Rider, you will need to manually reference the file by dragging it from the file system window, or by right-clicking, and using the context menu to reference the file in chat. + +![Rider Context Menu](../../screenshots/rider_context_menu.png) + +### Step 6: Verify Framework setup is completed + +1. Answer any questions that the AI prompts you with, and wait for it to complete. 2. The framework will automatically generate the `copilot-instructions.md` file 3. The framework should also generate a series of files in a folder named `.docs` +4. Review these documents for accuracy, and fix any problems you see. -### Step 8: Have the AI conduct Architecture Review +### Step 7: Follow the instructions from the `README.md` file to run eShop locally -Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! +Follow the instructions in the `README.md` file at the base of the eShop Repository to setup the application locally. You'll want to run the application using Aspire, and Docker, so that you can debug the application. Ensure that you can reach the Blazor Customer Portal, and that you can add an item from the catalog to your cart before you continue. ## Next challenge -Now that you've setup the AI to be able to better understand and work within your repository, it's time to [understand how to write requirements!](./2-requirements.md) \ No newline at end of file +Now that you've setup the AI to be able to better understand and work within your repository, it's time to [understand how to write requirements!](./2-requirements.md) + +[^1]: For more information, see [Container Runtime](https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=linux%2Cunix&pivots=dotnet-cli#container-runtime) +[^2]: _VS Code supports all features, Visual Studio 2022 17.14.13 and Jetbrains IDEs require workarounds noted through the workshop_ \ No newline at end of file diff --git a/goals/dotnet/2-requirements.md b/goals/dotnet/2-requirements.md index a9cf79a..76cbb0c 100644 --- a/goals/dotnet/2-requirements.md +++ b/goals/dotnet/2-requirements.md @@ -16,7 +16,7 @@ Your mission is to **design and document a new feature** for the eShop reference Before you begin, familiarize yourself with the existing eShop architecture by reviewing: -- **Architecture Diagrams**: `architectureDiagrams/*.md` - Architecture documentation created by GitHub Copilot +- **AI Generated documentation**: `docs/*.md` - Project and Architecture documentation created by GitHub Copilot - **Current Services**: Identity, Catalog, Basket, Ordering, Webhooks, Mobile.BFF - **Technology Stack**: .NET 9, Aspire, PostgreSQL, Redis, RabbitMQ, Blazor @@ -39,161 +39,15 @@ Before you begin, familiarize yourself with the existing eShop architecture by r ### 🎨 **Your Own Idea** Create something unique that fits the e-commerce domain and showcases modern software engineering practices. -## πŸ“ Requirements Template +## πŸ“ Requirements Generation -Create a new markdown file named `feature-[your-feature-name].md` in a directory named `/backlog`. Here's a sample structure that can help! (also, see our example feature in the `exercise-files` folder!): +Pass your idea with as much detail as you'd like to the `/create-spec` prompt. The AI will then generate a `.docs/specs` folder, with a specification detailing what it understands of your requirements. You will want to go through all of these documents, and correct any mistakes, add anything it missed, or take off features and functionality you don't want it to implement. -```markdown -# Feature: [Your Feature Name] - -## πŸ“– Executive Summary - -### Business Value -- [ ] **Problem Statement**: What business problem does this solve? -- [ ] **Target Users**: Who will use this feature? -- [ ] **Success Metrics**: How will you measure success? -- [ ] **Business Impact**: Revenue, user engagement, operational efficiency? - -### Technical Alignment -- [ ] **Architecture Fit**: How does this align with the microservices architecture? -- [ ] **Service Boundaries**: Which services will be affected or created? -- [ ] **Data Ownership**: Which service owns the feature's data? - -## 🎯 Feature Requirements - -### Functional Requirements -1. **[Requirement ID]**: [Clear, testable requirement] - - **Acceptance Criteria**: - - Given [context] - - When [action] - - Then [expected outcome] - - **Priority**: Must Have / Should Have / Could Have / Won't Have - -2. **[Next Requirement]**... - -### Non-Functional Requirements -- **Performance**: Response time, throughput expectations -- **Scalability**: Expected load, growth patterns -- **Security**: Authentication, authorization, data protection -- **Reliability**: Availability, error handling, recovery -- **Usability**: User experience considerations - -## πŸ—οΈ Technical Design - -### Service Architecture -- **New Services**: What new microservices need to be created? -- **Modified Services**: Which existing services need changes? -- **Service Communication**: How will services communicate? (sync/async) -- **Data Flow**: Map the data flow through your feature - -### Database Design -- **New Tables/Collections**: Schema design -- **Data Relationships**: How does your data relate to existing entities? -- **Migration Strategy**: How will you handle schema changes? - -### Event Design -- **Domain Events**: What events will your feature publish? -- **Integration Events**: How will you integrate with other services? -- **Event Handlers**: What background processing is needed? - -### API Design - -# Example API endpoints - -GET /api/[service]/[resource] -POST /api/[service]/[resource] -PUT /api/[service]/[resource]/{id} -DELETE /api/[service]/[resource]/{id} - -## πŸ”„ Implementation Roadmap - -### Phase 1: Foundation (Week 1-2) -- [ ] Service scaffolding -- [ ] Database schema -- [ ] Basic CRUD operations - -### Phase 2: Core Features (Week 3-4) -- [ ] Business logic implementation -- [ ] Event integration -- [ ] API development - -### Phase 3: Integration (Week 5-6) -- [ ] Frontend integration -- [ ] Service communication -- [ ] End-to-end testing - -### Phase 4: Polish (Week 7-8) -- [ ] Performance optimization -- [ ] Security hardening -- [ ] Documentation - -## πŸ§ͺ Testing Strategy - -### Unit Testing -- [ ] Service layer tests -- [ ] Domain logic tests -- [ ] Repository tests - -### Integration Testing -- [ ] API endpoint tests -- [ ] Database integration tests -- [ ] Event handler tests - -### End-to-End Testing -- [ ] User workflow tests -- [ ] Cross-service integration tests -- [ ] Performance tests - -## πŸ“Š Monitoring & Observability - -### Metrics -- [ ] Business metrics to track -- [ ] Technical metrics to monitor -- [ ] SLA/SLO definitions - -### Logging -- [ ] Structured logging requirements -- [ ] Log correlation across services -- [ ] Security audit logging - -### Alerting -- [ ] Critical alerts -- [ ] Performance degradation alerts -- [ ] Business metric alerts - -## 🚨 Risk Assessment - -### Technical Risks -- **Risk**: [Description] - - **Probability**: High/Medium/Low - - **Impact**: High/Medium/Low - - **Mitigation**: [Strategy] - -### Business Risks -- **Risk**: [Description] - - **Mitigation**: [Strategy] - -## πŸŽ“ Decision Log - -Use this section to document key decisions made during feature design: - -### Decision 1: [Title] -- **Context**: Why was this decision needed? -- **Options Considered**: What alternatives were evaluated? -- **Decision**: What was chosen? -- **Rationale**: Why was this the best choice? -- **Consequences**: What are the implications? - -## πŸ“š References - -- [ ] External APIs or services referenced -- [ ] Design patterns used -- [ ] Industry best practices followed -- [ ] Performance benchmarks -``` + > [!IMPORTANT] + > Try to be specific! Don't just tell the AI: "add a rewards system", give it details, such as: `create a customer loyalty program where for every $1 spent on the store, the customer earns 10 points. And for each 1,000 points the customer can redeem those points for $10 off their next purchase. Show the customer's point balance on their profile. And show the number of points earned under each item on the product page` > [!TIP] - > Try using Copilot to have it write your requirements for you! Copy the template, and surround it with <|TEMPLATE_START|><|TEMPLATE_END|>, and describe to the AI the Feature you'd like to plan! Then review and edit the generated markdown file to ensure that it matches what you want! + > Super-pro tip! You can create your requirements in a markdown file and then reference it to the AI in the same way we've referenced other files. We have a sample requirements-template.md file in this repository that has a great starter template to use for feeding detailed requirements to GitHub Copilot! [Check it out!](../../requirements-template.md) ## βœ… Success Criteria @@ -248,23 +102,23 @@ Your feature requirements document should demonstrate: Remember: **Good requirements are the foundation of great software**. Take your time to think through the problem space before jumping into solutions. The eShop application is a reference for modern software engineering practicesβ€”your feature should exemplify the same level of thoughtfulness and technical excellence. -**Start by creating your feature file and begin documenting your thinking process. Use Chat mode to help you if you're stuck!** +**Once you have a well defined specification, you can start work!** -When you're created your requirements file, prompt Copilot in Agent Mode: +When you're created your specs, prompt Copilot in Agent Mode: -`Plan #feature-[your-feature-name].md` +`/execute-tasks` -This should trigger the planning process. The AI should validate and produce an implementation plan, and ask if you're ready to start! When you're ready to continue: +You can pass it alone, or reference the specific task id from the `tasks.md` file you'd like to start with. Remember to help the AI keep track of completed tasks, so that you can easily start new conversations as context windows fill up. You can have the AI pickup on a specific task id, and sub-task with the same command: -`Act: #feature-[your-feature-name].md` +`/execute-task Resume 03bd0240-fdcc-48a9-832c-71c44193a375 task 1.10` From here, the AI will begin implementing your feature. Ensure you interact with the AI often, running unit tests, building and validating it's progress, provide feedback. Continue to use this process as you go until your feature is completed! ```mermaid flowchart LR - Plan[Plan
#story] --> Act[Act
#story] - Act --> Status[Status
#story] - Status --> Debug[Debug
#story] - Debug --> Plan + Plan[Plan
/create-spec] --> Act[Act
/execute-tasks] + Act --> Status[Status
/generate-report] + Status --> Debug[Debug
/startDebugging] + Debug --> Act style Plan stroke:#4F8EF7,stroke-width:2px style Act stroke:#4F8EF7,stroke-width:2px style Status stroke:#4F8EF7,stroke-width:2px diff --git a/goals/java/1-setup.md b/goals/java/1-setup.md index 4154c02..a856e26 100644 --- a/goals/java/1-setup.md +++ b/goals/java/1-setup.md @@ -1,41 +1,32 @@ ## πŸš€ Setting up the AI Assisted Coding Framework in your project -This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: +This framework integrates several powerful MCP (Model Context Protocol) tools to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references - **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Sequential Thinking MCP**: Assists the LLM with ordering tasks, and breaking down complex ideas +- **Microsoft.Learn MCP**: Give your LLM access to the entire Microsoft Learn knowledgebase! Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites - **Node.js 16+** (for MCP tools) -- **VS Code** with GitHub Copilot extension +- **IDE** with GitHub Copilot[^2] +- **Java** 17+ +- **Gradle 7.5+** or **Maven 3.5+** - **Git** for version control ## πŸ› οΈ Installation & Setup -### Step 1: Clone and Copy Framework Files +### Step 1: Clone The Framework Repository #### Windows Terminal: ```powershell # Clone this repository git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace 'your-project-path' with the actual path to your project -robocopy . "C:\path\to\your-project" /E /XD .git ``` -#### Linux / OSX Terminal: -```bash -git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace '/path/to/your-project' with the actual path to your project -rsync -av --exclude='.git' . /path/to/your-project/ -``` +We will use the files in this repository once you've setup your local workspace. Keep them somewhere easy to access, we recommend a folder such as `C:\github\` or `~/github` on Linux & OSX. ### Step 2 (optional): Change the MCP Configuration @@ -49,26 +40,47 @@ See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker -### Step 3: Open Project in VS Code +> [!IMPORTANT] +> If you intend to do this, please do this before coming to the workshop, and ensure they are setup and configured. This can take time to setup and troubleshoot, so be prepared. Our recommendation is to use the NodeJS versions of the tools. + +### Step 3: Clone the Spring Petclinic Repository + +You'll be building this challenge using the popular Petclinic demo repository from Spring. Clone the [petclinic](https://github.com/spring-projects/spring-petclinic/) Repository from the Spring team to an easy to access location on your machine. + +### Step 4: Copy the Framework to the petclinic repository +Copy the `.github` and `.vscode` folders from the AI-Assisted-Coding repository to the root of your petclinic repository. An example script below assumes you cloned both repositories to the root of `C:\github` or `~/github` respectively. + +#### Powershell ```powershell -# Open your project in VS Code -code . +cd c:\github\AI-Assisted-Coding +robocopy . "C:\github\spring-petclinic" /E /XD .git +``` + +#### Bash +```bash +cd ~/github +rsync -av --exclude='.git' . ~/github/spring-petclinic ``` -### Step 4: Run the Analyze Workflow -Run the `/analyze-product` prompt to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. -### Step 5: Verify GitHub Copilot Integration +### Step 5: Run the Analyze Workflow + +Open the petclinic Solution using VS Code or your preferrred IDE. + +Run the `/analyze-product` prompt in Copilot Agent Mode to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. + +### Step 6: Verify Framework setup is completed -1. Ensure GitHub Copilot extension is installed and activated +1. Answer any questions that the AI prompts you with, and wait for it to complete. 2. The framework will automatically generate the `copilot-instructions.md` file 3. The framework should also generate a series of files in a folder named `.docs` +4. Review these documents for accuracy, and fix any problems you see. -### Step 8: Have the AI conduct Architecture Review +### Step 7: Follow the instructions from the `README.md` file to run petclinic locally -Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! +Follow the instructions in the `README.md` file at the base of the petclinic Repository to setup the application locally. You'll want to ensure that you can reach the application, search for owners, and see a list of veterinarians. ## Next challenge diff --git a/goals/java/2-requirements.md b/goals/java/2-requirements.md index f090b5c..4913711 100644 --- a/goals/java/2-requirements.md +++ b/goals/java/2-requirements.md @@ -1,8 +1,8 @@ -# Pet Clinic Feature Development Challenge +# Spring PetClinic Feature Development Challenge ## 🎯 Challenge Overview -Your mission is to **design and document a new feature** for the Pet Clinic reference application. This challenge will teach you how to write comprehensive feature requirements that integrate seamlessly with the ConPort workflow and architectural patterns we've created. +Your mission is to **design and document a new feature** for the PetClinic reference application. This challenge will teach you how to write comprehensive feature requirements that integrate seamlessly with the ConPort workflow and architectural patterns we've created. ## πŸ“‹ What You'll Learn @@ -14,186 +14,36 @@ Your mission is to **design and document a new feature** for the Pet Clinic refe ## πŸ—οΈ Architecture Context -Before you begin, familiarize yourself with the existing Pet Clinic architecture by reviewing: +Before you begin, familiarize yourself with the existing PetClinic architecture by reviewing: -- **Architecture Diagrams**: `architectureDiagrams/*.md` - Architecture documentation created by GitHub Copilot +- **AI Generated documentation**: `docs/*.md` - Project and Architecture documentation created by GitHub Copilot - **Current Services**: Identity, Catalog, Basket, Ordering, Webhooks, Mobile.BFF - **Technology Stack**: .NET 9, Aspire, PostgreSQL, Redis, RabbitMQ, Blazor ## 🎲 Feature Ideas (Choose One or Create Your Own) ### πŸ’‘ **Beginner Level** -- **Pet Images**: Add images to pet profiles for easier identification -- **Pet Details**: Enhance the pet profile to add more detailed information. Breed, weight, etc. -- **Integrate Social Login**: Add OIDC support using Entra, Auth0, or another social login provider +- **Pet Profile**: Add the ability to upload a photo for a customer's pet ### πŸ”₯ **Intermediate Level** -- **Pet Visit Enhanced Details**: Add ability to upload x-rays, details around diagnostics, tagging, and vet's notes. Add the ability to select which vet the pet saw as well. -- **Customer Portal**: Customer portal where a customer can edit their data and manage their pet's profiles +- **Veterinarian Schedule**: Veterinarian appointment schedule view +- **Loyalty Program**: Points-based rewards system with tier benefits ### πŸš€ **Advanced Level** -- **Pet Adoption System**: Pet adoptions with a public view of adotable pet profiles, and management page in the existing UI for managing pet's available for adoption -- **Veterinarian Schedule**: Add a full schedule system for scheduling visits -- **Customer Portal**: Add scheduling to customer portal with calendar view +- **Real-time Notifications**: Notify the customer using SMS when their next appointment is! ### 🎨 **Your Own Idea** -Create something unique that fits the Veterinary Services domain and showcases modern software engineering practices. +Create something unique that fits the veterinarian domain and showcases modern software engineering practices. -## πŸ“ Requirements Template +## πŸ“ Requirements Generation -Create a new markdown file named `feature-[your-feature-name].md` in a directory named `/backlog`. Here's a sample structure that can help! (also, see our example feature in the `exercise-files` folder!): +Pass your idea with as much detail as you'd like to the `/create-spec` prompt. The AI will then generate a `.docs/specs` folder, with a specification detailing what it understands of your requirements. You will want to go through all of these documents, and correct any mistakes, add anything it missed, or take off features and functionality you don't want it to implement. -```markdown -# Feature: [Your Feature Name] - -## πŸ“– Executive Summary - -### Business Value -- [ ] **Problem Statement**: What business problem does this solve? -- [ ] **Target Users**: Who will use this feature? -- [ ] **Success Metrics**: How will you measure success? -- [ ] **Business Impact**: Revenue, user engagement, operational efficiency? - -### Technical Alignment -- [ ] **Architecture Fit**: How does this align with the microservices architecture? -- [ ] **Service Boundaries**: Which services will be affected or created? -- [ ] **Data Ownership**: Which service owns the feature's data? - -## 🎯 Feature Requirements - -### Functional Requirements -1. **[Requirement ID]**: [Clear, testable requirement] - - **Acceptance Criteria**: - - Given [context] - - When [action] - - Then [expected outcome] - - **Priority**: Must Have / Should Have / Could Have / Won't Have - -2. **[Next Requirement]**... - -### Non-Functional Requirements -- **Performance**: Response time, throughput expectations -- **Scalability**: Expected load, growth patterns -- **Security**: Authentication, authorization, data protection -- **Reliability**: Availability, error handling, recovery -- **Usability**: User experience considerations - -## πŸ—οΈ Technical Design - -### Service Architecture -- **New Services**: What new microservices need to be created? -- **Modified Services**: Which existing services need changes? -- **Service Communication**: How will services communicate? (sync/async) -- **Data Flow**: Map the data flow through your feature - -### Database Design -- **New Tables/Collections**: Schema design -- **Data Relationships**: How does your data relate to existing entities? -- **Migration Strategy**: How will you handle schema changes? - -### Event Design -- **Domain Events**: What events will your feature publish? -- **Integration Events**: How will you integrate with other services? -- **Event Handlers**: What background processing is needed? - -### API Design - -# Example API endpoints - -GET /api/[service]/[resource] -POST /api/[service]/[resource] -PUT /api/[service]/[resource]/{id} -DELETE /api/[service]/[resource]/{id} - -## πŸ”„ Implementation Roadmap - -### Phase 1: Foundation (Week 1-2) -- [ ] Service scaffolding -- [ ] Database schema -- [ ] Basic CRUD operations - -### Phase 2: Core Features (Week 3-4) -- [ ] Business logic implementation -- [ ] Event integration -- [ ] API development - -### Phase 3: Integration (Week 5-6) -- [ ] Frontend integration -- [ ] Service communication -- [ ] End-to-end testing - -### Phase 4: Polish (Week 7-8) -- [ ] Performance optimization -- [ ] Security hardening -- [ ] Documentation - -## πŸ§ͺ Testing Strategy - -### Unit Testing -- [ ] Service layer tests -- [ ] Domain logic tests -- [ ] Repository tests - -### Integration Testing -- [ ] API endpoint tests -- [ ] Database integration tests -- [ ] Event handler tests - -### End-to-End Testing -- [ ] User workflow tests -- [ ] Cross-service integration tests -- [ ] Performance tests - -## πŸ“Š Monitoring & Observability - -### Metrics -- [ ] Business metrics to track -- [ ] Technical metrics to monitor -- [ ] SLA/SLO definitions - -### Logging -- [ ] Structured logging requirements -- [ ] Log correlation across services -- [ ] Security audit logging - -### Alerting -- [ ] Critical alerts -- [ ] Performance degradation alerts -- [ ] Business metric alerts - -## 🚨 Risk Assessment - -### Technical Risks -- **Risk**: [Description] - - **Probability**: High/Medium/Low - - **Impact**: High/Medium/Low - - **Mitigation**: [Strategy] - -### Business Risks -- **Risk**: [Description] - - **Mitigation**: [Strategy] - -## πŸŽ“ Decision Log - -Use this section to document key decisions made during feature design: - -### Decision 1: [Title] -- **Context**: Why was this decision needed? -- **Options Considered**: What alternatives were evaluated? -- **Decision**: What was chosen? -- **Rationale**: Why was this the best choice? -- **Consequences**: What are the implications? - -## πŸ“š References - -- [ ] External APIs or services referenced -- [ ] Design patterns used -- [ ] Industry best practices followed -- [ ] Performance benchmarks -``` + > [!IMPORTANT] + > Try to be specific! Don't just tell the AI: "add a rewards system", give it details, such as: `create a customer loyalty program where for every $1 spent on services, the customer earns 10 points. And for each 1,000 points the customer can redeem those points for $10 off their next visit. Show the customer's point balance on their profile. And show the number of points earned under each visit in their pet's record` > [!TIP] - > Try using Copilot to have it write your requirements for you! Copy the template, and surround it with <|TEMPLATE_START|><|TEMPLATE_END|>, and describe to the AI the Feature you'd like to plan! Then review and edit the generated markdown file to ensure that it matches what you want! + > Super-pro tip! You can create your requirements in a markdown file and then reference it to the AI in the same way we've referenced other files. We have a sample requirements-template.md file in this repository that has a great starter template to use for feeding detailed requirements to GitHub Copilot! [Check it out!](../../requirements-template.md) ## βœ… Success Criteria @@ -246,25 +96,25 @@ Your feature requirements document should demonstrate: ## πŸŽ‰ Ready to Begin? -Remember: **Good requirements are the foundation of great software**. Take your time to think through the problem space before jumping into solutions. The Pet Clinic application is a reference for modern software engineering practicesβ€”your feature should exemplify the same level of thoughtfulness and technical excellence. +Remember: **Good requirements are the foundation of great software**. Take your time to think through the problem space before jumping into solutions. The PetClinic application is a reference for modern software engineering practicesβ€”your feature should exemplify the same level of thoughtfulness and technical excellence. -**Start by creating your feature file and begin documenting your thinking process. Use Chat mode to help you if you're stuck!** +**Once you have a well defined specification, you can start work!** -When you're created your requirements file, prompt Copilot in Agent Mode: +When you're created your specs, prompt Copilot in Agent Mode: -`Plan #feature-[your-feature-name].md` +`/execute-tasks` -This should trigger the planning process. The AI should validate and produce an implementation plan, and ask if you're ready to start! When you're ready to continue: +You can pass it alone, or reference the specific task id from the `tasks.md` file you'd like to start with. Remember to help the AI keep track of completed tasks, so that you can easily start new conversations as context windows fill up. You can have the AI pickup on a specific task id, and sub-task with the same command: -`Act: #feature-[your-feature-name].md` +`/execute-task Resume 03bd0240-fdcc-48a9-832c-71c44193a375 task 1.10` From here, the AI will begin implementing your feature. Ensure you interact with the AI often, running unit tests, building and validating it's progress, provide feedback. Continue to use this process as you go until your feature is completed! ```mermaid flowchart LR - Plan[Plan
#story] --> Act[Act
#story] - Act --> Status[Status
#story] - Status --> Debug[Debug
#story] - Debug --> Plan + Plan[Plan
/create-spec] --> Act[Act
/execute-tasks] + Act --> Status[Status
/generate-report] + Status --> Debug[Debug
/startDebugging] + Debug --> Act style Plan stroke:#4F8EF7,stroke-width:2px style Act stroke:#4F8EF7,stroke-width:2px style Status stroke:#4F8EF7,stroke-width:2px diff --git a/goals/python/1-setup.md b/goals/python/1-setup.md index 68108f4..b4375e6 100644 --- a/goals/python/1-setup.md +++ b/goals/python/1-setup.md @@ -1,41 +1,31 @@ ## πŸš€ Setting up the AI Assisted Coding Framework in your project -This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: +This framework integrates several powerful MCP (Model Context Protocol) tools to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references - **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Sequential Thinking MCP**: Assists the LLM with ordering tasks, and breaking down complex ideas +- **Microsoft.Learn MCP**: Give your LLM access to the entire Microsoft Learn knowledgebase! Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites - **Node.js 16+** (for MCP tools) -- **VS Code** with GitHub Copilot extension +- **IDE** with GitHub Copilot[^1] +- **Docker** is recommended, or you can use the devcontainer. - **Git** for version control ## πŸ› οΈ Installation & Setup -### Step 1: Clone and Copy Framework Files +### Step 1: Clone The Framework Repository #### Windows Terminal: ```powershell # Clone this repository git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace 'your-project-path' with the actual path to your project -robocopy . "C:\path\to\your-project" /E /XD .git ``` -#### Linux / OSX Terminal: -```bash -git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace '/path/to/your-project' with the actual path to your project -rsync -av --exclude='.git' . /path/to/your-project/ -``` +We will use the files in this repository once you've setup your local workspace. Keep them somewhere easy to access, we recommend a folder such as `C:\github\` or `~/github` on Linux & OSX. ### Step 2 (optional): Change the MCP Configuration @@ -49,26 +39,47 @@ See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker -### Step 3: Open Project in VS Code +> [!IMPORTANT] +> If you intend to do this, please do this before coming to the workshop, and ensure they are setup and configured. This can take time to setup and troubleshoot, so be prepared. Our recommendation is to use the NodeJS versions of the tools. + +### Step 3: Clone the Inventree Repository + +You'll be building this challenge using the popular Inventree demo repository. Clone the [Inventree](https://github.com/inventree/InvenTree) Repository from github to an easy to access location on your machine. + +### Step 4: Copy the Framework to the inventree repository +Copy the `.github` and `.vscode` folders from the AI-Assisted-Coding repository to the root of your inventree repository. An example script below assumes you cloned both repositories to the root of `C:\github` or `~/github` respectively. + +#### Powershell ```powershell -# Open your project in VS Code -code . +cd c:\github\AI-Assisted-Coding +robocopy . "C:\github\inventree" /E /XD .git +``` + +#### Bash +```bash +cd ~/github +rsync -av --exclude='.git' . ~/github/inventree ``` -### Step 4: Run the Analyze Workflow -Run the `/analyze-product` prompt to analyze your workspace and generate the documents that help the spec-driven development workflow operate smoothly. -### Step 5: Verify GitHub Copilot Integration +### Step 5: Run the Analyze Workflow + +Open the inventree Solution using VS Code or your preferrred IDE. + +Run the `/analyze-product` prompt in Copilot Agent Mode to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. + +### Step 6: Verify Framework setup is completed -1. Ensure GitHub Copilot extension is installed and activated +1. Answer any questions that the AI prompts you with, and wait for it to complete. 2. The framework will automatically generate the `copilot-instructions.md` file 3. The framework should also generate a series of files in a folder named `.docs` +4. Review these documents for accuracy, and fix any problems you see. -### Step 8: Have the AI conduct Architecture Review +### Step 7: Follow the instructions from the `README.md` file to run inventree locally -Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! +Follow the instructions in the `README.md` file at the base of the inventree Repository to setup the application locally. You'll want to ensure that you can reach the application, search inventory, and manage suppliers. ## Next challenge diff --git a/goals/python/2-requirements.md b/goals/python/2-requirements.md index 301f1f4..da2b6f7 100644 --- a/goals/python/2-requirements.md +++ b/goals/python/2-requirements.md @@ -16,7 +16,7 @@ Your mission is to **design and document a new feature** for the InvenTree refer Before you begin, familiarize yourself with the existing InvenTree architecture by reviewing: -- **Architecture Diagrams**: `architectureDiagrams/*.md` - Architecture documentation created by GitHub Copilot +- **AI Generated documentation**: `docs/*.md` - Project and Architecture documentation created by GitHub Copilot - **Current Services**: Parts, Stock, Build, Orders, Reports, Admin - **Technology Stack**: Python 3.11, Django, React @@ -34,161 +34,15 @@ Before you begin, familiarize yourself with the existing InvenTree architecture ### 🎨 **Your Own Idea** Create something unique that fits the inventory management application and showcases modern software engineering practices. -## πŸ“ Requirements Template +## πŸ“ Requirements Generation -Create a new markdown file named `feature-[your-feature-name].md` in a directory named `/backlog`. Here's a sample structure that can help! (also, see our example feature in the `exercise-files` folder!): +Pass your idea with as much detail as you'd like to the `/create-spec` prompt. The AI will then generate a `.docs/specs` folder, with a specification detailing what it understands of your requirements. You will want to go through all of these documents, and correct any mistakes, add anything it missed, or take off features and functionality you don't want it to implement. -```markdown -# Feature: [Your Feature Name] - -## πŸ“– Executive Summary - -### Business Value -- [ ] **Problem Statement**: What business problem does this solve? -- [ ] **Target Users**: Who will use this feature? -- [ ] **Success Metrics**: How will you measure success? -- [ ] **Business Impact**: Revenue, user engagement, operational efficiency? - -### Technical Alignment -- [ ] **Architecture Fit**: How does this align with the microservices architecture? -- [ ] **Service Boundaries**: Which services will be affected or created? -- [ ] **Data Ownership**: Which service owns the feature's data? - -## 🎯 Feature Requirements - -### Functional Requirements -1. **[Requirement ID]**: [Clear, testable requirement] - - **Acceptance Criteria**: - - Given [context] - - When [action] - - Then [expected outcome] - - **Priority**: Must Have / Should Have / Could Have / Won't Have - -2. **[Next Requirement]**... - -### Non-Functional Requirements -- **Performance**: Response time, throughput expectations -- **Scalability**: Expected load, growth patterns -- **Security**: Authentication, authorization, data protection -- **Reliability**: Availability, error handling, recovery -- **Usability**: User experience considerations - -## πŸ—οΈ Technical Design - -### Service Architecture -- **New Services**: What new microservices need to be created? -- **Modified Services**: Which existing services need changes? -- **Service Communication**: How will services communicate? (sync/async) -- **Data Flow**: Map the data flow through your feature - -### Database Design -- **New Tables/Collections**: Schema design -- **Data Relationships**: How does your data relate to existing entities? -- **Migration Strategy**: How will you handle schema changes? - -### Event Design -- **Domain Events**: What events will your feature publish? -- **Integration Events**: How will you integrate with other services? -- **Event Handlers**: What background processing is needed? - -### API Design - -# Example API endpoints - -GET /api/[service]/[resource] -POST /api/[service]/[resource] -PUT /api/[service]/[resource]/{id} -DELETE /api/[service]/[resource]/{id} - -## πŸ”„ Implementation Roadmap - -### Phase 1: Foundation (Week 1-2) -- [ ] Service scaffolding -- [ ] Database schema -- [ ] Basic CRUD operations - -### Phase 2: Core Features (Week 3-4) -- [ ] Business logic implementation -- [ ] Event integration -- [ ] API development - -### Phase 3: Integration (Week 5-6) -- [ ] Frontend integration -- [ ] Service communication -- [ ] End-to-end testing - -### Phase 4: Polish (Week 7-8) -- [ ] Performance optimization -- [ ] Security hardening -- [ ] Documentation - -## πŸ§ͺ Testing Strategy - -### Unit Testing -- [ ] Service layer tests -- [ ] Domain logic tests -- [ ] Repository tests - -### Integration Testing -- [ ] API endpoint tests -- [ ] Database integration tests -- [ ] Event handler tests - -### End-to-End Testing -- [ ] User workflow tests -- [ ] Cross-service integration tests -- [ ] Performance tests - -## πŸ“Š Monitoring & Observability - -### Metrics -- [ ] Business metrics to track -- [ ] Technical metrics to monitor -- [ ] SLA/SLO definitions - -### Logging -- [ ] Structured logging requirements -- [ ] Log correlation across services -- [ ] Security audit logging - -### Alerting -- [ ] Critical alerts -- [ ] Performance degradation alerts -- [ ] Business metric alerts - -## 🚨 Risk Assessment - -### Technical Risks -- **Risk**: [Description] - - **Probability**: High/Medium/Low - - **Impact**: High/Medium/Low - - **Mitigation**: [Strategy] - -### Business Risks -- **Risk**: [Description] - - **Mitigation**: [Strategy] - -## πŸŽ“ Decision Log - -Use this section to document key decisions made during feature design: - -### Decision 1: [Title] -- **Context**: Why was this decision needed? -- **Options Considered**: What alternatives were evaluated? -- **Decision**: What was chosen? -- **Rationale**: Why was this the best choice? -- **Consequences**: What are the implications? - -## πŸ“š References - -- [ ] External APIs or services referenced -- [ ] Design patterns used -- [ ] Industry best practices followed -- [ ] Performance benchmarks -``` + > [!IMPORTANT] + > Try to be specific! Don't just tell the AI: "add a rewards system", give it details, such as: `create a customer loyalty program where for every $1 spent on the store, the customer earns 10 points. And for each 1,000 points the customer can redeem those points for $10 off their next purchase. Show the customer's point balance on their profile. And show the number of points earned under each item on the product page` > [!TIP] - > Try using Copilot to have it write your requirements for you! Copy the template, and surround it with <|TEMPLATE_START|><|TEMPLATE_END|>, and describe to the AI the Feature you'd like to plan! Then review and edit the generated markdown file to ensure that it matches what you want! + > Super-pro tip! You can create your requirements in a markdown file and then reference it to the AI in the same way we've referenced other files. We have a sample requirements-template.md file in this repository that has a great starter template to use for feeding detailed requirements to GitHub Copilot! [Check it out!](../../requirements-template.md) ## βœ… Success Criteria @@ -243,23 +97,23 @@ Your feature requirements document should demonstrate: Remember: **Good requirements are the foundation of great software**. Take your time to think through the problem space before jumping into solutions. The InvenTree application is a reference for modern software engineering practicesβ€”your feature should exemplify the same level of thoughtfulness and technical excellence. -**Start by creating your feature file and begin documenting your thinking process. Use Chat mode to help you if you're stuck!** +**Once you have a well defined specification, you can start work!** -When you're created your requirements file, prompt Copilot in Agent Mode: +When you're created your specs, prompt Copilot in Agent Mode: -`Plan #feature-[your-feature-name].md` +`/execute-tasks` -This should trigger the planning process. The AI should validate and produce an implementation plan, and ask if you're ready to start! When you're ready to continue: +You can pass it alone, or reference the specific task id from the `tasks.md` file you'd like to start with. Remember to help the AI keep track of completed tasks, so that you can easily start new conversations as context windows fill up. You can have the AI pickup on a specific task id, and sub-task with the same command: -`Act: #feature-[your-feature-name].md` +`/execute-task Resume 03bd0240-fdcc-48a9-832c-71c44193a375 task 1.10` From here, the AI will begin implementing your feature. Ensure you interact with the AI often, running unit tests, building and validating it's progress, provide feedback. Continue to use this process as you go until your feature is completed! ```mermaid flowchart LR - Plan[Plan
#story] --> Act[Act
#story] - Act --> Status[Status
#story] - Status --> Debug[Debug
#story] - Debug --> Plan + Plan[Plan
/create-spec] --> Act[Act
/execute-tasks] + Act --> Status[Status
/generate-report] + Status --> Debug[Debug
/startDebugging] + Debug --> Act style Plan stroke:#4F8EF7,stroke-width:2px style Act stroke:#4F8EF7,stroke-width:2px style Status stroke:#4F8EF7,stroke-width:2px diff --git a/goals/typescript/1-setup.md b/goals/typescript/1-setup.md index bca44f6..d64df0a 100644 --- a/goals/typescript/1-setup.md +++ b/goals/typescript/1-setup.md @@ -1,41 +1,31 @@ ## πŸš€ Setting up the AI Assisted Coding Framework in your project -This framework integrates two powerful MCP (Model Context Protocol) servers to supercharge your development workflow: +This framework integrates several powerful MCP (Model Context Protocol) tools to supercharge your development workflow: - **Context7 MCP**: Provides live documentation and code snippet retrieval for authoritative technical references - **Memory MCP**: Delivers persistent project memory, decision tracking, and knowledge graph capabilities +- **Sequential Thinking MCP**: Assists the LLM with ordering tasks, and breaking down complex ideas +- **Microsoft.Learn MCP**: Give your LLM access to the entire Microsoft Learn knowledgebase! Together, they transform GitHub Copilot into an intelligent development assistant that remembers project context, tracks architectural decisions, and maintains comprehensive project knowledge across sessions. ## πŸ“‹ Prerequisites - **Node.js 16+** (for MCP tools) -- **VS Code** with GitHub Copilot extension +- **IDE** with GitHub Copilot[^1] +- **Docker** is recommended, or you can use the devcontainer. - **Git** for version control ## πŸ› οΈ Installation & Setup -### Step 1: Clone and Copy Framework Files +### Step 1: Clone The Framework Repository #### Windows Terminal: ```powershell # Clone this repository git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace 'your-project-path' with the actual path to your project -robocopy . "C:\path\to\your-project" /E /XD .git ``` -#### Linux / OSX Terminal: -```bash -git clone https://github.com/ChrisMcKee1/AI-Assisted-Coding.git -cd AI-Assisted-Coding - -# Copy all framework files to your project's root directory -# Replace '/path/to/your-project' with the actual path to your project -rsync -av --exclude='.git' . /path/to/your-project/ -``` +We will use the files in this repository once you've setup your local workspace. Keep them somewhere easy to access, we recommend a folder such as `C:\github\` or `~/github` on Linux & OSX. ### Step 2 (optional): Change the MCP Configuration @@ -49,27 +39,47 @@ See the [Sequential Thinking MCP Readme](https://github.com/modelcontextprotocol See the [Memory MCP Readme](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) for details on how to configure it using Docker -### Step 3: Open Project in VS Code +> [!IMPORTANT] +> If you intend to do this, please do this before coming to the workshop, and ensure they are setup and configured. This can take time to setup and troubleshoot, so be prepared. Our recommendation is to use the NodeJS versions of the tools. + +### Step 3: Clone the ngLibrary Repository + +You'll be building this challenge using the ngLibrary demo repository. Clone the [ngLibrary](https://github.com/mrWh1te/ngLibrary/) Repository from github to an easy to access location on your machine. +### Step 4: Copy the Framework to the ngLibrary repository + +Copy the `.github` and `.vscode` folders from the AI-Assisted-Coding repository to the root of your ngLibrary repository. An example script below assumes you cloned both repositories to the root of `C:\github` or `~/github` respectively. + +#### Powershell ```powershell -# Open your project in VS Code -code . +cd c:\github\AI-Assisted-Coding +robocopy . "C:\github\ngLibrary" /E /XD .git ``` -### Step 4: Run the Analyze Workflow +#### Bash +```bash +cd ~/github +rsync -av --exclude='.git' . ~/github/ngLibrary +``` + + +### Step 5: Run the Analyze Workflow + +Open the ngLibrary Solution using VS Code or your preferrred IDE. -Run the `/analyze-product` prompt to analyze your workspace and generate the documents that help the spec-driven development workflow operate smoothly. +Run the `/analyze-product` prompt in Copilot Agent Mode to analyze your woskpace and generate the documents that help the spec-driven development workflow operate smoothly. -### Step 5: Verify GitHub Copilot Integration +### Step 6: Verify Framework setup is completed -1. Ensure GitHub Copilot extension is installed and activated +1. Answer any questions that the AI prompts you with, and wait for it to complete. 2. The framework will automatically generate the `copilot-instructions.md` file 3. The framework should also generate a series of files in a folder named `.docs` +4. Review these documents for accuracy, and fix any problems you see. -### Step 8: Have the AI conduct Architecture Review +### Step 7: Follow the instructions from the `README.md` file to run ngLibrary locally -Have Copilot Create an Architecture Review of the repo. Take a look at the `README.md` in the AI Assisted Coding framework for help on how to conduct the Architecture review. When it completes, you should end up with a new folder named `architectureDiagrams` that contains 5 ore more markdown files with charts, documentation, and more about the eShop Application! Make sure you pass the #codebase token in your command, so that VS Code will give the AI access to the codebase for the context! +Follow the instructions in the `README.md` file at the base of the ngLibrary Repository to setup the application locally. You'll want to ensure that you can reach the application, search inventory, and manage suppliers. ## Next challenge diff --git a/goals/typescript/2-requirements.md b/goals/typescript/2-requirements.md index abc82a0..03f880b 100644 --- a/goals/typescript/2-requirements.md +++ b/goals/typescript/2-requirements.md @@ -16,7 +16,7 @@ Your mission is to **design and document a new feature** for the ngLibrary refer Before you begin, familiarize yourself with the existing ngLibrary architecture by reviewing: -- **Architecture Diagrams**: `architectureDiagrams/*.md` - Architecture documentation created by GitHub Copilot +- **AI Generated documentation**: `docs/*.md` - Project and Architecture documentation created by GitHub Copilot - **Current Modules**: App, Books, Cart, Checkout, Layouts, Core - **Technology Stack**: Typescript 4, Angular 11 @@ -38,161 +38,15 @@ Before you begin, familiarize yourself with the existing ngLibrary architecture ### 🎨 **Your Own Idea** Create something unique that fits the library management domain and showcases modern software engineering practices. -## πŸ“ Requirements Template +## πŸ“ Requirements Generation -Create a new markdown file named `feature-[your-feature-name].md` in a directory named `/backlog`. Here's a sample structure that can help! (also, see our example feature in the `exercise-files` folder!): +Pass your idea with as much detail as you'd like to the `/create-spec` prompt. The AI will then generate a `.docs/specs` folder, with a specification detailing what it understands of your requirements. You will want to go through all of these documents, and correct any mistakes, add anything it missed, or take off features and functionality you don't want it to implement. -```markdown -# Feature: [Your Feature Name] - -## πŸ“– Executive Summary - -### Business Value -- [ ] **Problem Statement**: What business problem does this solve? -- [ ] **Target Users**: Who will use this feature? -- [ ] **Success Metrics**: How will you measure success? -- [ ] **Business Impact**: Revenue, user engagement, operational efficiency? - -### Technical Alignment -- [ ] **Architecture Fit**: How does this align with the microservices architecture? -- [ ] **Service Boundaries**: Which services will be affected or created? -- [ ] **Data Ownership**: Which service owns the feature's data? - -## 🎯 Feature Requirements - -### Functional Requirements -1. **[Requirement ID]**: [Clear, testable requirement] - - **Acceptance Criteria**: - - Given [context] - - When [action] - - Then [expected outcome] - - **Priority**: Must Have / Should Have / Could Have / Won't Have - -2. **[Next Requirement]**... - -### Non-Functional Requirements -- **Performance**: Response time, throughput expectations -- **Scalability**: Expected load, growth patterns -- **Security**: Authentication, authorization, data protection -- **Reliability**: Availability, error handling, recovery -- **Usability**: User experience considerations - -## πŸ—οΈ Technical Design - -### Service Architecture -- **New Services**: What new microservices need to be created? -- **Modified Services**: Which existing services need changes? -- **Service Communication**: How will services communicate? (sync/async) -- **Data Flow**: Map the data flow through your feature - -### Database Design -- **New Tables/Collections**: Schema design -- **Data Relationships**: How does your data relate to existing entities? -- **Migration Strategy**: How will you handle schema changes? - -### Event Design -- **Domain Events**: What events will your feature publish? -- **Integration Events**: How will you integrate with other services? -- **Event Handlers**: What background processing is needed? - -### API Design - -# Example API endpoints - -GET /api/[service]/[resource] -POST /api/[service]/[resource] -PUT /api/[service]/[resource]/{id} -DELETE /api/[service]/[resource]/{id} - -## πŸ”„ Implementation Roadmap - -### Phase 1: Foundation (Week 1-2) -- [ ] Service scaffolding -- [ ] Database schema -- [ ] Basic CRUD operations - -### Phase 2: Core Features (Week 3-4) -- [ ] Business logic implementation -- [ ] Event integration -- [ ] API development - -### Phase 3: Integration (Week 5-6) -- [ ] Frontend integration -- [ ] Service communication -- [ ] End-to-end testing - -### Phase 4: Polish (Week 7-8) -- [ ] Performance optimization -- [ ] Security hardening -- [ ] Documentation - -## πŸ§ͺ Testing Strategy - -### Unit Testing -- [ ] Service layer tests -- [ ] Domain logic tests -- [ ] Repository tests - -### Integration Testing -- [ ] API endpoint tests -- [ ] Database integration tests -- [ ] Event handler tests - -### End-to-End Testing -- [ ] User workflow tests -- [ ] Cross-service integration tests -- [ ] Performance tests - -## πŸ“Š Monitoring & Observability - -### Metrics -- [ ] Business metrics to track -- [ ] Technical metrics to monitor -- [ ] SLA/SLO definitions - -### Logging -- [ ] Structured logging requirements -- [ ] Log correlation across services -- [ ] Security audit logging - -### Alerting -- [ ] Critical alerts -- [ ] Performance degradation alerts -- [ ] Business metric alerts - -## 🚨 Risk Assessment - -### Technical Risks -- **Risk**: [Description] - - **Probability**: High/Medium/Low - - **Impact**: High/Medium/Low - - **Mitigation**: [Strategy] - -### Business Risks -- **Risk**: [Description] - - **Mitigation**: [Strategy] - -## πŸŽ“ Decision Log - -Use this section to document key decisions made during feature design: - -### Decision 1: [Title] -- **Context**: Why was this decision needed? -- **Options Considered**: What alternatives were evaluated? -- **Decision**: What was chosen? -- **Rationale**: Why was this the best choice? -- **Consequences**: What are the implications? - -## πŸ“š References - -- [ ] External APIs or services referenced -- [ ] Design patterns used -- [ ] Industry best practices followed -- [ ] Performance benchmarks -``` + > [!IMPORTANT] + > Try to be specific! Don't just tell the AI: "add a rewards system", give it details, such as: `create a customer loyalty program where for every $1 spent on the store, the customer earns 10 points. And for each 1,000 points the customer can redeem those points for $10 off their next purchase. Show the customer's point balance on their profile. And show the number of points earned under each item on the product page` > [!TIP] - > Try using Copilot to have it write your requirements for you! Copy the template, and surround it with <|TEMPLATE_START|><|TEMPLATE_END|>, and describe to the AI the Feature you'd like to plan! Then review and edit the generated markdown file to ensure that it matches what you want! + > Super-pro tip! You can create your requirements in a markdown file and then reference it to the AI in the same way we've referenced other files. We have a sample requirements-template.md file in this repository that has a great starter template to use for feeding detailed requirements to GitHub Copilot! [Check it out!](../../requirements-template.md) ## βœ… Success Criteria @@ -247,23 +101,23 @@ Your feature requirements document should demonstrate: Remember: **Good requirements are the foundation of great software**. Take your time to think through the problem space before jumping into solutions. The ngLibrary application is a reference for modern software engineering practicesβ€”your feature should exemplify the same level of thoughtfulness and technical excellence. -**Start by creating your feature file and begin documenting your thinking process. Use Chat mode to help you if you're stuck!** +**Once you have a well defined specification, you can start work!** -When you're created your requirements file, prompt Copilot in Agent Mode: +When you're created your specs, prompt Copilot in Agent Mode: -`Plan #feature-[your-feature-name].md` +`/execute-tasks` -This should trigger the planning process. The AI should validate and produce an implementation plan, and ask if you're ready to start! When you're ready to continue: +You can pass it alone, or reference the specific task id from the `tasks.md` file you'd like to start with. Remember to help the AI keep track of completed tasks, so that you can easily start new conversations as context windows fill up. You can have the AI pickup on a specific task id, and sub-task with the same command: -`Act: #feature-[your-feature-name].md` +`/execute-task Resume 03bd0240-fdcc-48a9-832c-71c44193a375 task 1.10` From here, the AI will begin implementing your feature. Ensure you interact with the AI often, running unit tests, building and validating it's progress, provide feedback. Continue to use this process as you go until your feature is completed! ```mermaid flowchart LR - Plan[Plan
#story] --> Act[Act
#story] - Act --> Status[Status
#story] - Status --> Debug[Debug
#story] - Debug --> Plan + Plan[Plan
/create-spec] --> Act[Act
/execute-tasks] + Act --> Status[Status
/generate-report] + Status --> Debug[Debug
/startDebugging] + Debug --> Act style Plan stroke:#4F8EF7,stroke-width:2px style Act stroke:#4F8EF7,stroke-width:2px style Status stroke:#4F8EF7,stroke-width:2px diff --git a/requirements-template.md b/requirements-template.md new file mode 100644 index 0000000..44f757f --- /dev/null +++ b/requirements-template.md @@ -0,0 +1,146 @@ +# Feature: [Your Feature Name] + +## πŸ“– Executive Summary + +### Business Value +- [ ] **Problem Statement**: What business problem does this solve? +- [ ] **Target Users**: Who will use this feature? +- [ ] **Success Metrics**: How will you measure success? +- [ ] **Business Impact**: Revenue, user engagement, operational efficiency? + +### Technical Alignment +- [ ] **Architecture Fit**: How does this align with the microservices architecture? +- [ ] **Service Boundaries**: Which services will be affected or created? +- [ ] **Data Ownership**: Which service owns the feature's data? + +## 🎯 Feature Requirements + +### Functional Requirements +1. **[Requirement ID]**: [Clear, testable requirement] + - **Acceptance Criteria**: + - Given [context] + - When [action] + - Then [expected outcome] + - **Priority**: Must Have / Should Have / Could Have / Won't Have + +2. **[Next Requirement]**... + +### Non-Functional Requirements +- **Performance**: Response time, throughput expectations +- **Scalability**: Expected load, growth patterns +- **Security**: Authentication, authorization, data protection +- **Reliability**: Availability, error handling, recovery +- **Usability**: User experience considerations + +## πŸ—οΈ Technical Design + +### Service Architecture +- **New Services**: What new microservices need to be created? +- **Modified Services**: Which existing services need changes? +- **Service Communication**: How will services communicate? (sync/async) +- **Data Flow**: Map the data flow through your feature + +### Database Design +- **New Tables/Collections**: Schema design +- **Data Relationships**: How does your data relate to existing entities? +- **Migration Strategy**: How will you handle schema changes? + +### Event Design +- **Domain Events**: What events will your feature publish? +- **Integration Events**: How will you integrate with other services? +- **Event Handlers**: What background processing is needed? + +### API Design + +# Example API endpoints + +GET /api/[service]/[resource] +POST /api/[service]/[resource] +PUT /api/[service]/[resource]/{id} +DELETE /api/[service]/[resource]/{id} + +## πŸ”„ Implementation Roadmap + +### Phase 1: Foundation (Week 1-2) +- [ ] Service scaffolding +- [ ] Database schema +- [ ] Basic CRUD operations + +### Phase 2: Core Features (Week 3-4) +- [ ] Business logic implementation +- [ ] Event integration +- [ ] API development + +### Phase 3: Integration (Week 5-6) +- [ ] Frontend integration +- [ ] Service communication +- [ ] End-to-end testing + +### Phase 4: Polish (Week 7-8) +- [ ] Performance optimization +- [ ] Security hardening +- [ ] Documentation + +## πŸ§ͺ Testing Strategy + +### Unit Testing +- [ ] Service layer tests +- [ ] Domain logic tests +- [ ] Repository tests + +### Integration Testing +- [ ] API endpoint tests +- [ ] Database integration tests +- [ ] Event handler tests + +### End-to-End Testing +- [ ] User workflow tests +- [ ] Cross-service integration tests +- [ ] Performance tests + +## πŸ“Š Monitoring & Observability + +### Metrics +- [ ] Business metrics to track +- [ ] Technical metrics to monitor +- [ ] SLA/SLO definitions + +### Logging +- [ ] Structured logging requirements +- [ ] Log correlation across services +- [ ] Security audit logging + +### Alerting +- [ ] Critical alerts +- [ ] Performance degradation alerts +- [ ] Business metric alerts + +## 🚨 Risk Assessment + +### Technical Risks +- **Risk**: [Description] + - **Probability**: High/Medium/Low + - **Impact**: High/Medium/Low + - **Mitigation**: [Strategy] + +### Business Risks +- **Risk**: [Description] + - **Mitigation**: [Strategy] + +## πŸŽ“ Decision Log + +Use this section to document key decisions made during feature design: + +### Decision 1: [Title] +- **Context**: Why was this decision needed? +- **Options Considered**: What alternatives were evaluated? +- **Decision**: What was chosen? +- **Rationale**: Why was this the best choice? +- **Consequences**: What are the implications? + +## πŸ“š References + +- [ ] External APIs or services referenced +- [ ] Design patterns used +- [ ] Industry best practices followed +- [ ] Performance benchmarks \ No newline at end of file diff --git a/screenshots/rider_context_menu.png b/screenshots/rider_context_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..76ced88ade53cdeeaa1907997e384c33b02281ef GIT binary patch literal 59370 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 C5&Me( literal 0 HcmV?d00001 From c2dbccf23cf24f06bb8df896970a8b92604c58ba Mon Sep 17 00:00:00 2001 From: Zack Way Date: Thu, 28 Aug 2025 13:16:35 -0400 Subject: [PATCH 5/6] Update prerequisites in README.md for clarity and accuracy --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 828557a..d5dfb58 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ Developers today agree that AI code assistant tools are useful for easy, repeata ## Prerequisites - Clone the Spec Driven Coding Framework repository: https://github.com/seiggy/AI-Assisted-Coding -- [Install & start Docker Desktop](https://docs.docker.com/get-started/get-docker/) -or - -- [Install & Start Podman](https://podman.io/docs/installation) +- [NodeJS 16+](https://nodejs.org/) for MCP servers +- **Container Platform** An OCI compliant container runtime is recommended for .NET, and Python developers + - [Docker Desktop](https://www.docker.com/products/docker-desktop) + - [Podman](https://podman.io/) [^1] @@ -23,7 +23,7 @@ or
For Java Developers -- Clone the Pet Clinic repository: https://github.com/azure-samples/spring-petclinic-microservices +- Clone the Pet Clinic repository: https://github.com/spring-projects/spring-petclinic/
@@ -131,3 +131,5 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope ### Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies. + +[^1]: For more information, see [Container Runtime](https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=linux%2Cunix&pivots=dotnet-cli#container-runtime) \ No newline at end of file From 0bd2082d96f1d7346584202c606dfccadb240512 Mon Sep 17 00:00:00 2001 From: Zack Way Date: Thu, 28 Aug 2025 13:17:09 -0400 Subject: [PATCH 6/6] Update repository link in README.md for accuracy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5dfb58..c918408 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Developers today agree that AI code assistant tools are useful for easy, repeata ## Prerequisites -- Clone the Spec Driven Coding Framework repository: https://github.com/seiggy/AI-Assisted-Coding +- Clone the Spec Driven Coding Framework repository: https://github.com/ChrisMcKee1/AI-Assisted-Coding - [NodeJS 16+](https://nodejs.org/) for MCP servers - **Container Platform** An OCI compliant container runtime is recommended for .NET, and Python developers