<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mouad Bourbian</title>
    <description>The latest articles on Forem by Mouad Bourbian (@mouadbourbian).</description>
    <link>https://forem.com/mouadbourbian</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3760236%2Fbffa9c02-f5ed-4936-a263-23ed04b113b7.png</url>
      <title>Forem: Mouad Bourbian</title>
      <link>https://forem.com/mouadbourbian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mouadbourbian"/>
    <language>en</language>
    <item>
      <title>⏱️ The Weekend Speedrun: Building the "Awesome Copilot Guide" with my AI Terminal Sidekick</title>
      <dc:creator>Mouad Bourbian</dc:creator>
      <pubDate>Thu, 12 Feb 2026 20:59:52 +0000</pubDate>
      <link>https://forem.com/mouadbourbian/the-weekend-speedrun-building-the-awesome-copilot-guide-with-my-ai-terminal-sidekick-39m0</link>
      <guid>https://forem.com/mouadbourbian/the-weekend-speedrun-building-the-awesome-copilot-guide-with-my-ai-terminal-sidekick-39m0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What I Built
&lt;/h2&gt;

&lt;p&gt;I built the &lt;strong&gt;Awesome Copilot Guide&lt;/strong&gt;, an AI assistant that helps developers navigate the massive &lt;a href="https://github.com/github/awesome-copilot" rel="noopener noreferrer"&gt;Awesome GitHub Copilot&lt;/a&gt; ecosystem. Think of it as your personal guide through hundreds of agents, skills, and prompts, so you don't have to scroll endlessly trying to find what you need.&lt;/p&gt;

&lt;p&gt;Here's the thing: I had only &lt;strong&gt;3 days to build&lt;/strong&gt; this from scratch for the &lt;a href="https://dev.to/mouadbourbian/awesome-copilot-guide-your-personal-navigator-for-the-awesome-github-copilot-2gal"&gt;Algolia Agent Studio Challenge&lt;/a&gt;. Started coding on February 6th, deadline was February 8th at 23:59 PT. When you're working under that kind of pressure, having a solid programming buddy is everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 16&lt;/strong&gt; with &lt;strong&gt;TypeScript&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; and &lt;strong&gt;Shadcn UI&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Algolia Agent Studio&lt;/strong&gt; powered by &lt;strong&gt;Google Gemini&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of browsing through a giant markdown file, you just tell the chat what you're working on, and it finds the perfect Copilot resources for your specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎬 Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://mouadbourbian.github.io/Awesome-Copilot-Guide/" rel="noopener noreferrer"&gt;https://mouadbourbian.github.io/Awesome-Copilot-Guide&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;GitHub Link:&lt;/strong&gt; &lt;a href="https://github.com/MouadBourbian/Awesome-Copilot-Guide" rel="noopener noreferrer"&gt;https://github.com/MouadBourbian/Awesome-Copilot-Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd3cuj46lv8shekqqp1er.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd3cuj46lv8shekqqp1er.png" alt="Demo Screenshot" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🤖 My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;Honestly? Game changer.&lt;/p&gt;

&lt;p&gt;When you're facing a tight deadline for a project that doesn't yet exist, every minute counts. GitHub Copilot CLI didn't just save me time; it kept me in flow.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚙️ The Setup That Saved Me
&lt;/h3&gt;

&lt;p&gt;First thing I did was create a &lt;a href="https://github.com/MouadBourbian/Awesome-Copilot-Guide/blob/main/.devcontainer/devcontainer.json" rel="noopener noreferrer"&gt;devcontainer.json&lt;/a&gt; with Node.js, TypeScript, and the GitHub CLI. This gave me an isolated environment where I could experiment freely without worrying about messing up my local setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Node.js &amp;amp; TypeScript"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"features"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ghcr.io/devcontainers/features/github-cli:1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffw36vcw4oi7ro2x2dspf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffw36vcw4oi7ro2x2dspf.png" alt="Copilot CLI ready to go" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Starting fresh — Copilot CLI ready to initialize the project&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🤯 What Surprised Me
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51gpn8hr1ji6g7c3epr5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51gpn8hr1ji6g7c3epr5.png" alt="Asking about project setup" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Copilot CLI asking thoughtful questions instead of blindly following commands&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokkdcyrwqiht491lmrbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokkdcyrwqiht491lmrbu.png" alt="Initializing Next.js" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;One command, and it sets up the entire Next.js project with best practices&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It doesn't just blindly execute.&lt;/strong&gt; When I asked it to initialize the project with Next.js and Vite, it actually stopped and questioned me. It caught that something was off — Next.js has its own build system (Turbopack/Webpack), so using it with Vite doesn't make sense. Instead of just running a broken command, it asked me to clarify what I really wanted. That kind of critical thinking? That's exactly what you want from a pair programmer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fciajebxxywpcz6ell1tq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fciajebxxywpcz6ell1tq.png" alt="Workflow automation" width="800" height="425"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Setting up CI/CD workflows — Copilot knows exactly what's needed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ekereapz3az3d42f3z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ekereapz3az3d42f3z5.png" alt="Project initialized" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Summary of everything created — dependencies, config, the works&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The summaries are clutch.&lt;/strong&gt; After completing a task, it always gave me a quick rundown. I never had to wonder what just happened.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 The Git Workflow That Actually Works
&lt;/h3&gt;

&lt;p&gt;Here's my favorite part: when I finished a feature, I could tell Copilot CLI to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"&lt;code&gt;@.github/instructions/commit-conventions.instructions.md&lt;/code&gt; First, check the files to be staged in Git. Then view their diff. After that, add them step by step and commit them based on the changes, following the conventional commit process outlined in the instructions. Depending on what makes sense, a commit can either contain a single file or multiple files. Finally, push the changes to the remote repository."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu6k8800euylgibu50zm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu6k8800euylgibu50zm.png" alt="Committing with Copilot" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The best part: it handles Git commits with logical groupings and proper messages&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk94ngxewcc41m54ksxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk94ngxewcc41m54ksxl.png" alt="Writing commit message" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;You can also review the commit message before it's committed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Below is an overview of the process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Review what changed&lt;/li&gt;
&lt;li&gt;Group files logically (dependencies separate from config, features separate from docs)&lt;/li&gt;
&lt;li&gt;Write meaningful commit messages that follow conventions&lt;/li&gt;
&lt;li&gt;Push everything&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And because I had custom commit guidelines in my project, it followed those too.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌍 Real-World Impact
&lt;/h3&gt;

&lt;p&gt;The deadline was Sunday at midnight (PT). By the end, I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A working Next.js app with TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind and Shadcn UI fully configured&lt;/li&gt;
&lt;li&gt;Algolia integration and Agent Studio setup&lt;/li&gt;
&lt;li&gt;GitHub Actions for CI/CD&lt;/li&gt;
&lt;li&gt;Comprehensive documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All because I spent more time thinking about &lt;em&gt;what&lt;/em&gt; to build than &lt;em&gt;how&lt;/em&gt; to build it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧰 What I Used It For
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Project initialization&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Workflow setup&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Git management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used &lt;strong&gt;Claude Sonnet 4.5&lt;/strong&gt; as the model, which gave me solid reasoning and thoughtful suggestions throughout.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✨ The Bottom Line
&lt;/h3&gt;

&lt;p&gt;Building under pressure is stressful. Having an AI sidekick that can handle the tedious setup, catch mistakes, and keep everything organized? That's what let me focus on solving the actual problem instead of fighting with configuration files.&lt;/p&gt;

&lt;p&gt;If you're on the fence about trying GitHub Copilot CLI, here's my advice: just start with &lt;code&gt;gh copilot&lt;/code&gt; on your next project. Ask it to help with one small thing. You'll see what I mean.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>🚀 Awesome Copilot Guide: Your Personal Navigator for the Awesome GitHub Copilot</title>
      <dc:creator>Mouad Bourbian</dc:creator>
      <pubDate>Sun, 08 Feb 2026 17:38:58 +0000</pubDate>
      <link>https://forem.com/mouadbourbian/awesome-copilot-guide-your-personal-navigator-for-the-awesome-github-copilot-2gal</link>
      <guid>https://forem.com/mouadbourbian/awesome-copilot-guide-your-personal-navigator-for-the-awesome-github-copilot-2gal</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia"&gt;Algolia Agent Studio Challenge&lt;/a&gt;: Consumer-Facing Conversational Experiences&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 What I Built
&lt;/h2&gt;

&lt;p&gt;I built the &lt;strong&gt;Awesome Copilot Guide&lt;/strong&gt;, think of it as your friendly AI sidekick that helps you navigate the massive &lt;a href="https://github.com/github/awesome-copilot" rel="noopener noreferrer"&gt;Awesome GitHub Copilot&lt;/a&gt; ecosystem without losing your mind.&lt;/p&gt;

&lt;p&gt;Here's the thing: there are hundreds of agents, skills, and prompts out there. Finding the right one for your specific workflow? It's like trying to find that one specific LEGO piece in a giant bin.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;Awesome Copilot Guide&lt;/em&gt; cuts through the noise. Just tell it what you're working on (your tech stack, your current task, whatever) and it'll hook you up with a personalized, curated list of recommendations. No more endless scrolling through markdown lists!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 16&lt;/strong&gt; with &lt;strong&gt;TypeScript&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; and &lt;strong&gt;Shadcn UI&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Algolia Agent Studio&lt;/strong&gt; powered by &lt;strong&gt;Google Gemini&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎬 Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://mouadbourbian.github.io/Awesome-Copilot-Guide/" rel="noopener noreferrer"&gt;https://mouadbourbian.github.io/Awesome-Copilot-Guide&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;GitHub Link:&lt;/strong&gt; &lt;a href="https://github.com/MouadBourbian/Awesome-Copilot-Guide" rel="noopener noreferrer"&gt;https://github.com/MouadBourbian/Awesome-Copilot-Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd3cuj46lv8shekqqp1er.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd3cuj46lv8shekqqp1er.png" alt="Demo Screenshot" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;p&gt;I used Algolia Agent Studio to ground the conversational AI in real time, searchable data. Here's how everything comes together:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. 📊 Indexing the Data
&lt;/h3&gt;

&lt;p&gt;The magic starts with good data. I built a custom Python script (&lt;a href="https://github.com/MouadBourbian/Awesome-Copilot-Guide/blob/main/scripts/algolia_generate_index.py" rel="noopener noreferrer"&gt;algolia_generate_index.py&lt;/a&gt;) that fetches the raw &lt;a href="https://github.github.io/awesome-copilot/llms.txt" rel="noopener noreferrer"&gt;llms.txt&lt;/a&gt; file from the official Awesome Copilot GitHub Pages. The script parses through the markdown structure and transforms it into structured data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: What the resource is called&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type&lt;/strong&gt;: Whether it's an Agent, Skill, or Prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description&lt;/strong&gt;: What it actually does (the value prop)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL&lt;/strong&gt;: Direct link to dive deeper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;algolia_generate_index.py:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
This module provides functionality to fetch and parse an &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;llms.txt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; file
from a remote URL and convert it into a JSON index.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.error&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;URLError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPError&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_and_parse_llms_txt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Fetches the llms.txt content from the given URL, parses the markdown links,
    and saves the structured data to a JSON file.

    Args:
        url (str): The URL of the llms.txt file.
        output_file (str): The path where the JSON output will be saved.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;current_section&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;General&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# Matches: - [Name](URL): Description
&lt;/span&gt;    &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;- \[(.*?)\]\((.*?)\): (.*)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fetching content from: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# 1. Fetch the content from the web
&lt;/span&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitlines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;

                &lt;span class="c1"&gt;# Detect Section (e.g., ## Agents)
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;## &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;current_section&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;## &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;

                &lt;span class="c1"&gt;# Extract Item Details
&lt;/span&gt;                &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;full_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

                    &lt;span class="c1"&gt;# 2. Convert Raw URL to GitHub Viewer URL
&lt;/span&gt;                    &lt;span class="n"&gt;github_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;full_url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://raw.githubusercontent.com/github/awesome-copilot/main/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/github/awesome-copilot/tree/main/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;

                    &lt;span class="c1"&gt;# Clean ID
&lt;/span&gt;                    &lt;span class="n"&gt;safe_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[^a-zA-Z0-9]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                    &lt;span class="n"&gt;safe_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;safe_name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;object_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;current_section&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;safe_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

                    &lt;span class="n"&gt;type_singular&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;current_section&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current_section&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;current_section&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;

                    &lt;span class="c1"&gt;# Create Record
&lt;/span&gt;                    &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;objectID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;object_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;type_singular&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;github_url&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# 3. Save to File
&lt;/span&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Success! Processed &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; items.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Saved to: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;output_file&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP Error &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;URLError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;URL Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;except &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;IOError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;File system error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://github.github.io/awesome-copilot/llms.txt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;OUTPUT_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;awesome-copilot.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="nf"&gt;fetch_and_parse_llms_txt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OUTPUT_FILE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of this gets structured into a clean JSON index (&lt;code&gt;awesome-copilot.json&lt;/code&gt;) and uploaded directly through the Algolia Dashboard. To make filtering work smoothly, I configured the &lt;code&gt;type&lt;/code&gt; attribute as a facet in the index settings, so the agent can quickly narrow down results by resource type.&lt;/p&gt;

&lt;p&gt;You can check out the detailed setup steps I followed here: &lt;a href="https://github.com/MouadBourbian/Awesome-Copilot-Guide/blob/main/docs/Algolia.md" rel="noopener noreferrer"&gt;Algolia Configuration Guide&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 💬 The Conversational Experience
&lt;/h3&gt;

&lt;p&gt;On the frontend, I'm using the &lt;strong&gt;AI SDK&lt;/strong&gt; (&lt;code&gt;@ai-sdk/react&lt;/code&gt;) to connect directly to the Algolia Agent API. Instead of using a standard widget, this allowed me to wrap the powerful Algolia retrieval engine inside a fully custom &lt;strong&gt;Shadcn UI&lt;/strong&gt; interface. The &lt;code&gt;AlgoliaChat&lt;/code&gt; component streams responses in real time, creating that smooth, natural chat experience where the AI feels like a helpful sidekick on your team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;algolia-chat.tsx:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useChat&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DefaultChatTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ALGOLIA_APP_ID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;.algolia.net/agent-studio/1/agents/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;AGENT_ID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/completions?stream=true&amp;amp;compatibilityMode=ai-sdk-5`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-algolia-application-id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ALGOLIA_APP_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-algolia-api-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ALGOLIA_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 🎯 Targeted Prompting
&lt;/h3&gt;

&lt;p&gt;Quality control was key here. I engineered a two-layer defense against hallucinations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1: Index Configuration&lt;/strong&gt;&lt;br&gt;
I configured the index description in Agent Studio to explicitly state:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A catalog of GitHub Copilot agents, skills, instructions, prompts, and documentation for developers. Must be searched before any recommendation. This is the sole source of truth for all suggestions."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: Mandatory Search Protocol&lt;/strong&gt;&lt;br&gt;
I crafted a strict &lt;a href="https://github.com/MouadBourbian/Awesome-Copilot-Guide/blob/main/prompts/algolia-instructions.md" rel="noopener noreferrer"&gt;system prompt&lt;/a&gt; that forbids the model from guessing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;[...]

&lt;span class="gu"&gt;## Mandatory Search Protocol&lt;/span&gt;

&lt;span class="gs"&gt;**YOU ARE STRICTLY FORBIDDEN from providing final recommendations or answers without first searching the catalog.**&lt;/span&gt;

&lt;span class="gs"&gt;**Before every recommendation:**&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; &lt;span class="gs"&gt;**MUST search the catalog first:**&lt;/span&gt; No exceptions, even if you think you know the answer
&lt;span class="p"&gt;2.&lt;/span&gt; &lt;span class="gs"&gt;**MUST base all recommendations on actual search results:**&lt;/span&gt; Never rely on assumptions or memory
&lt;span class="p"&gt;3.&lt;/span&gt; &lt;span class="gs"&gt;**MUST verify resources exist and are current:**&lt;/span&gt; Links and details must come from search results
&lt;span class="p"&gt;4.&lt;/span&gt; &lt;span class="gs"&gt;**If search returns no results:**&lt;/span&gt; Try broader terms before concluding nothing exists

&lt;span class="gs"&gt;**Violations of this rule are unacceptable.**&lt;/span&gt; If you cannot search, you must inform the user that you cannot provide recommendations without search capability.

[...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This forces the Agent to query the Algolia index before answering anything, which means it can't just make stuff up. Every recommendation is grounded in real, verified resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;For a directory assistant like this, speed and accuracy aren't just nice to haves. They're everything. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎭 Eliminating Hallucinations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By using Algolia's retrieval as the foundation, the AI only recommends resources that actually exist in the catalog. It can't invent a link to a resource because it has to find it first. No more phantom recommendations!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 Contextual Relevance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Algolia's lightning fast search filters through hundreds of items in milliseconds. When someone asks for "Next.js tools," the system instantly narrows down the context, letting the LLM focus only on relevant results instead of fumbling through its general knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🏃 User Flow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The combination of Algolia's speed and streaming responses means users get actionable answers immediately. They spend less time searching and more time building. That's the whole point, right?&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>ai</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
