<?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: OLIVIER VANHESTE</title>
    <description>The latest articles on Forem by OLIVIER VANHESTE (@olivier_vanheste_62a5c2c6).</description>
    <link>https://forem.com/olivier_vanheste_62a5c2c6</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%2F2703934%2F952a0515-c945-4297-a917-aff8a10f60d3.png</url>
      <title>Forem: OLIVIER VANHESTE</title>
      <link>https://forem.com/olivier_vanheste_62a5c2c6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/olivier_vanheste_62a5c2c6"/>
    <language>en</language>
    <item>
      <title>Hack, Reflect, Look Forward: Building JH Link with Google Gemini</title>
      <dc:creator>OLIVIER VANHESTE</dc:creator>
      <pubDate>Mon, 02 Mar 2026 21:07:00 +0000</pubDate>
      <link>https://forem.com/olivier_vanheste_62a5c2c6/hack-reflect-look-forward-building-jh-link-with-google-gemini-glj</link>
      <guid>https://forem.com/olivier_vanheste_62a5c2c6/hack-reflect-look-forward-building-jh-link-with-google-gemini-glj</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/mlh-built-with-google-gemini-02-25-26"&gt;Built with Google Gemini: Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built with Google Gemini
&lt;/h2&gt;

&lt;p&gt;For the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;, I built &lt;strong&gt;JH Link&lt;/strong&gt; — a Progressive Web App with the tagline &lt;em&gt;"Your youth centre, in your pocket."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The app serves my local youth center, which runs activities for members aged 10–19 (and welcomes the wider community). Communication was fragmented: events were word-of-mouth, check-ins were manual, and members had no persistent sense of engagement when they weren't physically present.&lt;/p&gt;

&lt;p&gt;JH Link solves that with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Activity Feed&lt;/strong&gt; — filterable, searchable event list with real-time capacity indicators and one-tap registration or waitlist joining&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Digital Member Card&lt;/strong&gt; — a QR code (built with &lt;code&gt;qrcode.react&lt;/code&gt;) that encodes &lt;code&gt;&amp;lt;appUrl&amp;gt;/admin/checkin?uid=&amp;lt;userId&amp;gt;&lt;/code&gt;, scannable by staff directly in the app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gamification&lt;/strong&gt; — an XP and badge system: attendance earns points, milestones at 50 / 100 / 250 / 500 / 1000 XP, and four automatic badges (First Timer → Regular → Veteran → Legend) plus a bonus for completing your profile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard&lt;/strong&gt; — personalized home screen with an XP progress bar, badge shelf, and next 3 upcoming events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin Dashboard&lt;/strong&gt; — four panels: Members (activate/reject), Points (manual award/deduct), Activities (create/edit/cancel), and Check-In (QR scanner that marks attendance and triggers the XP award)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stack: Next.js (App Router), Supabase (auth + PostgreSQL with RLS + Storage), Tailwind CSS, Vercel. Built entirely inside a VS Code Dev Container using &lt;code&gt;bun&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before writing a single line of code, I ran a series of sparring sessions with Gemini on the web to settle the architecture. I described the problem space, the target audience, and the constraints (offline-capable PWA, minimal ops overhead, fast solo build), and we worked through the tradeoffs together — why Supabase over a custom backend, why Next.js App Router over Pages, how to structure RLS for a mixed member/admin user model, and what the gamification layer should look like at a schema level. Those early conversations produced the architecture document and the database schema before I opened VS Code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Gemini was my co-developer throughout the entire weekend build.&lt;/strong&gt; Every feature started as a conversation. I'd describe what I needed, Gemini would produce a draft, I'd review it, challenge it, and we'd iterate. The result was a feature-complete application shipped in roughly two days.&lt;/p&gt;

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

&lt;p&gt;Live demo: &lt;a href="https://jh-link.vercel.app/login" rel="noopener noreferrer"&gt;https://jh-link.vercel.app/login&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/pvxCczZUtH4" rel="noopener noreferrer"&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%2Fhyt77qvsfzji9b12j1o9.jpg" alt="JH Link Demo Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Technical skills
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Supabase RLS is subtle and unforgiving.&lt;/strong&gt; I came into the weekend thinking Row Level Security would be straightforward. In practice, a misconfigured policy fails &lt;em&gt;silently&lt;/em&gt; — the query just returns zero rows instead of an error. The trickiest part was the gamification layer: awarding points and badges needs to happen whether triggered by a member action or an admin check-in. The solution was a service-role client that bypasses RLS for those writes, but that meant I had to be very deliberate about &lt;em&gt;where&lt;/em&gt; that client is used, since a service-role key in the wrong place would be a serious security leak. Gemini helped me think through the permission model, but I still had to manually review every RLS policy and service-role call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js App Router has sharp async edges.&lt;/strong&gt; The mix of Server Components, Client Components, and Server Actions creates subtle boundaries. Several bugs came from mis-placed &lt;code&gt;await&lt;/code&gt;s or from a Server Action not having access to cookies the way I expected. One concrete example: the three Supabase client factories (&lt;code&gt;client.ts&lt;/code&gt;, &lt;code&gt;server.ts&lt;/code&gt;, &lt;code&gt;middleware.ts&lt;/code&gt;) each exist for a specific context, and using the wrong one causes silent auth failures. These are the kinds of bugs where the error message points you nowhere near the root cause.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PWA edge cases are platform-specific and fiddly.&lt;/strong&gt; The service worker cache invalidation strategy that works on Android often behaves differently on iOS Safari — especially around the install prompt and offline fallback pages. The generated &lt;code&gt;sw.js&lt;/code&gt; was a solid starting point but needed manual tuning for iOS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel data fetching matters.&lt;/strong&gt; The activities page fetches registration counts, the user's own registrations, &lt;em&gt;and&lt;/em&gt; their waitlist entries for the rendered activity IDs. Doing those three queries in sequence would be noticeably slow. Gemini suggested wrapping them in &lt;code&gt;Promise.all()&lt;/code&gt; immediately, which I kept — and it made a real difference in perceived load time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Soft skills &amp;amp; unexpected lessons
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Prompt quality directly determines output quality.&lt;/strong&gt; The clearest lesson of the weekend: vague prompts produce vague code. When I started framing requests as &lt;em&gt;"I need a Server Action that registers a user for an activity, enforcing membership, capacity, and deadline constraints, and returning a typed result object"&lt;/em&gt;, the output was immediately usable. When I said &lt;em&gt;"add registration logic"&lt;/em&gt;, it was a mess. Treating Gemini like a senior collaborator who needs full context — not a magic code button — changed everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never merge generated security-sensitive code without reading it.&lt;/strong&gt; The RLS policies and the service-role client usage are the two places where a bug isn't just a broken feature — it's a data exposure or privilege escalation. I learned to treat those sections with the same scrutiny I'd apply to a security audit, regardless of how confident the explanation sounded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed creates scope creep.&lt;/strong&gt; When you can generate features quickly, the temptation is to keep adding. I had rough implementations of a member messaging system and social reactions on activities before I cut them. Being fast doesn't mean you should keep going — knowing when to stop is a skill the AI can't help you with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Google Gemini Feedback
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What worked well
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Context retention within a long session was excellent.&lt;/strong&gt; I could say &lt;em&gt;"remember that the gamification runs via the service-role client"&lt;/em&gt; and Gemini would correctly propagate that constraint into the next feature's implementation without me restating it. This made multi-step features feel like a real dialogue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error reasoning saved significant debugging time.&lt;/strong&gt; When Supabase returned a cryptic error code, Gemini's ability to reason about &lt;em&gt;what the error likely means in this context&lt;/em&gt;, rank the possible causes, and suggest targeted fixes was faster than reading documentation cold. This happened several times with RLS policy errors and with the &lt;code&gt;pkce&lt;/code&gt; auth flow callback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boilerplate for well-known patterns was fast and accurate.&lt;/strong&gt; The three Supabase client factories, the &lt;code&gt;useTransition&lt;/code&gt;-based optimistic UI on the registration button, the &lt;code&gt;next/font/google&lt;/code&gt; setup, the PWA metadata in &lt;code&gt;layout.tsx&lt;/code&gt; — all of these are patterns that are tedious to type out correctly but well within Gemini's training data. Getting them right on the first pass was a genuine time saving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code organisation suggestions.&lt;/strong&gt; When I dumped a large feature request in one go, Gemini would often propose a sensible file split before writing any code. It suggested separating &lt;code&gt;ActivityCard.tsx&lt;/code&gt; from &lt;code&gt;RegistrationButton.tsx&lt;/code&gt; so the card could be a server-renderable component while only the button needed to be a Client Component. That's the kind of structural thinking I appreciated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where there was friction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Hallucinated API signatures.&lt;/strong&gt; On a couple of occasions, Gemini generated code using Supabase SDK methods or options that don't exist in the version I was using — most notably around the &lt;code&gt;count&lt;/code&gt; query option syntax. The code compiled fine and failed at runtime with an opaque error. This is the most dangerous failure mode: confidently wrong code that &lt;em&gt;looks&lt;/em&gt; right. Cross-referencing the actual Supabase docs became a habit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Over-engineering on the first pass.&lt;/strong&gt; When I asked for the gamification system, the initial output included an abstraction layer — a &lt;code&gt;GamificationEngine&lt;/code&gt; class with a plugin interface for future reward types. I needed a single &lt;code&gt;awardPoints()&lt;/code&gt; function that works now. Asking for simplicity became a recurring step; the phrase &lt;em&gt;"write the simplest version that satisfies these requirements"&lt;/em&gt; was something I used often.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging loops that don't converge.&lt;/strong&gt; If a bug had multiple possible causes, Gemini would sometimes propose a fix, I'd report it didn't work, and the next response would be a marginally different version of the same fix — without genuinely reconsidering the root cause. These loops required me to hard-reset: close the conversation, write a fresh prompt that described the symptom from scratch, and reframe the problem. That usually broke the loop, but it cost time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Occasional confidently wrong explanations.&lt;/strong&gt; A few times, Gemini explained &lt;em&gt;why&lt;/em&gt; something worked in a way that was plausible-sounding but subtly incorrect. I caught these by testing the claim against the actual behavior or the docs. The risk is not catching them — you end up with a mental model of your own codebase that's wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The VS Code extension ignored my project structure.&lt;/strong&gt; This was a persistent and frustrating friction point with the Gemini extension in VS Code: it consistently created new files under the repository root instead of under &lt;code&gt;src/&lt;/code&gt;, regardless of how I phrased the request. Every file it scaffolded — components, actions, route handlers — had to be manually moved or I had to explicitly spell out the full path in the prompt every single time. The web interface never had this problem; it was specific to how the extension interpreted workspace context. It wasn't a showstopper, but it broke flow repeatedly across the entire build.&lt;/p&gt;

&lt;h3&gt;
  
  
  The honest verdict
&lt;/h3&gt;

&lt;p&gt;Building a feature-complete application in a weekend would not have been possible to the same standard without Gemini. The productivity gain on well-defined, boilerplate-heavy work is real and large. But it's a force multiplier for someone who already understands the domain — not a substitute for understanding it. Every security-sensitive section required me to be fully present and skeptical. Every place I accepted output on trust, I eventually paid for.&lt;/p&gt;

&lt;p&gt;The two improvements I'd most want to see: better API version awareness (or at least a clear caveat when generating code against a specific SDK version) and a more deliberate root-cause debugging mode that explicitly backtracks rather than proposing incremental variants of a failing approach.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>geminireflections</category>
      <category>gemini</category>
    </item>
    <item>
      <title>JH Link: A PWA to Connect and Engage Our Local Youth Center</title>
      <dc:creator>OLIVIER VANHESTE</dc:creator>
      <pubDate>Sun, 01 Mar 2026 21:43:03 +0000</pubDate>
      <link>https://forem.com/olivier_vanheste_62a5c2c6/jh-link-a-pwa-to-connect-and-engage-our-local-youth-center-5ahb</link>
      <guid>https://forem.com/olivier_vanheste_62a5c2c6/jh-link-a-pwa-to-connect-and-engage-our-local-youth-center-5ahb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;This project is for my local youth center. While its main focus is on providing a vibrant hub for young people aged 10-19, the center maintains an open and welcoming atmosphere for the entire community. People of all ages are encouraged to drop in for a chat, grab a drink from the cafe, or even participate in activities. However, communication and engagement are often fragmented, relying on word-of-mouth and scattered social media posts. It can be hard for members to track activities, see who's attending, or feel a persistent sense of belonging when they aren't physically at the center. Administrators also spend significant time on manual tasks like check-ins and tracking participation.&lt;/p&gt;

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

&lt;p&gt;To address these challenges, I built &lt;strong&gt;JH Link&lt;/strong&gt;, a Progressive Web App (PWA) designed to be the digital heart of our youth center.&lt;/p&gt;

&lt;p&gt;It's a mobile-first application that provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Activity Feed:&lt;/strong&gt; A real-time list of upcoming events and activities that members can register for with a single tap.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Member Profiles:&lt;/strong&gt; A space for members to express themselves and see their engagement history.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Digital Member Card:&lt;/strong&gt; A QR-code-based virtual card for easy check-ins, replacing the need for physical cards.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Gamification:&lt;/strong&gt; A points and leveling system that rewards members for participating in activities, fostering friendly competition and sustained engagement.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Admin Dashboard:&lt;/strong&gt; A comprehensive backend for staff to manage activities, check in members, and oversee the points system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make participation easier, more rewarding, and to strengthen the community bond, even when members are apart.&lt;/p&gt;

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

&lt;p&gt;You can try out a live demo of the application here: &lt;a href="https://jh-link.vercel.app/login" rel="noopener noreferrer"&gt;https://jh-link.vercel.app/login&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a video walkthrough of the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/pvxCczZUtH4" rel="noopener noreferrer"&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%2Fhyt77qvsfzji9b12j1o9.jpg" alt="JH Link Demo Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The full source code is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/polcrosmol/jh-link" rel="noopener noreferrer"&gt;https://github.com/polcrosmol/jh-link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I developed JH Link over the weekend, leveraging a modern, full-stack TypeScript approach.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Framework:&lt;/strong&gt; &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; (using the App Router)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Backend &amp;amp; Database:&lt;/strong&gt; &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; for authentication, a PostgreSQL database with Row Level Security, and storage.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Deployment:&lt;/strong&gt; &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Styling:&lt;/strong&gt; &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;UI/UX:&lt;/strong&gt; The app is a fully Progressive Web App (PWA), installable on mobile devices for a native-like experience. It includes page transition animations and a navigation progress bar.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tooling:&lt;/strong&gt; I used &lt;code&gt;bun&lt;/code&gt; as the package manager and the entire development was done inside a VS Code Dev Container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A significant part of the development process involved working with an AI assistant. This co-development model was incredibly efficient. The AI handled much of the initial scaffolding, boilerplate code, and complex server actions, which allowed me to focus on the overall architecture, user experience, and critically reviewing the generated code to ensure its quality and correctness. We collaborated on everything from feature implementation to complex debugging of SQL policies and asynchronous JavaScript, enabling the creation of a feature-rich application in a very short amount of time.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Copilot Jira Planner — Turn Project Ideas into Jira-Ready Plans with AI</title>
      <dc:creator>OLIVIER VANHESTE</dc:creator>
      <pubDate>Sat, 14 Feb 2026 16:26:52 +0000</pubDate>
      <link>https://forem.com/olivier_vanheste_62a5c2c6/copilot-jira-planner-turn-project-ideas-into-jira-ready-plans-with-ai-iph</link>
      <guid>https://forem.com/olivier_vanheste_62a5c2c6/copilot-jira-planner-turn-project-ideas-into-jira-ready-plans-with-ai-iph</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;&lt;strong&gt;Copilot Jira Planner (&lt;code&gt;cjp&lt;/code&gt;)&lt;/strong&gt; is a terminal-native project planning tool that uses GitHub Copilot CLI as its AI engine. You describe a project idea in plain English, and it generates a fully structured Jira-compatible plan — complete with Epics, Stories, Tasks, story points, time estimates, and acceptance criteria.&lt;/p&gt;

&lt;p&gt;The problem it solves: every new project starts with the same tedious ritual — manually creating dozens of Jira issues, structuring them into epics, writing user stories, estimating effort. This tool automates that entire process in seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤖 &lt;strong&gt;AI-Powered Planning&lt;/strong&gt; — Describe your project in natural language, get a structured plan back&lt;/li&gt;
&lt;li&gt;🌲 &lt;strong&gt;Beautiful Terminal UI&lt;/strong&gt; — Tree and table views with color-coded priorities and status icons&lt;/li&gt;
&lt;li&gt;📤 &lt;strong&gt;Jira Export&lt;/strong&gt; — CSV and JSON export in Jira-compatible format for bulk import&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Direct Jira Sync&lt;/strong&gt; — Push plans directly to Jira via REST API (with dry-run preview)&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Iterative Refinement&lt;/strong&gt; — Refine existing plans with natural language instructions&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;Local Storage&lt;/strong&gt; — Plans persist locally for later viewing, editing, and exporting&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;🔗 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/polcrosmol/Copilot-Jira-Planner" rel="noopener noreferrer"&gt;polcrosmol/Copilot-Jira-Planner&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Images
&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%2Fqy50ina5a061ss44hx2p.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%2Fqy50ina5a061ss44hx2p.png" alt=" " width="800" height="608"&gt;&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%2Fy8tqvpx3qvmmjjs5pefo.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%2Fy8tqvpx3qvmmjjs5pefo.png" alt=" " width="528" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Plan
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cjp create &lt;span class="s2"&gt;"Build a simple todo app with user authentication"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  🤖 Invoking GitHub Copilot CLI to generate your plan...
  Project: "Build a simple todo app with user authentication"

  ✔ Plan generated successfully!

  ╔══════════════════════════════════════════════════════════════╗
  ║  🎯 Todo App with Auth                                      ║
  ╚══════════════════════════════════════════════════════════════╝

  Plan ID: 49484ee8  │  Epics: 4  │  Stories: 9  │  Tasks: 25  │  Story Points: 42

├── 🔴 [E-1] User Authentication (2 stories)
│   ├── ⬜ [E-1-S-1] As a new user, I want to register an account... [5sp]
│   │   ├── ⬜ [E-1-S-1-T-1] Create user database model and migration (2h)
│   │   ├── ⬜ [E-1-S-1-T-2] Build registration API endpoint (4h)
│   │   └── ⬜ [E-1-S-1-T-3] Create registration UI form (4h)
│   └── ⬜ [E-1-S-2] As a registered user, I want to log in and out... [5sp]
│       ├── ⬜ [E-1-S-2-T-1] Build login API endpoint (4h)
│       ├── ⬜ [E-1-S-2-T-2] Implement authentication middleware (2h)
│       ├── ⬜ [E-1-S-2-T-3] Create login UI and auth state management (4h)
│       └── ⬜ [E-1-S-2-T-4] Implement protected route guards (2h)
│
├── 🟠 [E-2] Todo CRUD Operations (3 stories)
│   └── ...
├── 🟡 [E-3] UI Polish and App Shell (2 stories)
│   └── ...
└── 🟠 [E-4] Project Setup and Deployment (2 stories)
    └── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Table View
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cjp view &lt;span class="nt"&gt;--mode&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────┬────────┬──────────────────────────────────┬──────────┬─────────┬────┬──────┐
│ ID             │ Type   │ Title                            │ Priority │ Status  │ SP │ Est. │
├────────────────┼────────┼──────────────────────────────────┼──────────┼─────────┼────┼──────┤
│ E-1            │ Epic   │ User Authentication              │ 🔴 high  │ ⬜ todo │    │      │
│ E-1-S-1        │ Story  │ As a new user, I want to...      │ 🔴 high  │ ⬜ todo │ 5  │      │
│ E-1-S-1-T-1    │ Task   │ Create user database model       │ 🟡 med   │ ⬜ todo │    │ 2h   │
│ E-1-S-1-T-2    │ Task   │ Build registration API endpoint  │ 🟡 med   │ ⬜ todo │    │ 4h   │
└────────────────┴────────┴──────────────────────────────────┴──────────┴─────────┴────┴──────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exporting and Jira Sync
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Export to Jira-compatible CSV&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;cjp &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; csv
  ✅ Exported plan to todo-app-with-auth-plan.csv

&lt;span class="c"&gt;# Preview what would be created in Jira&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;cjp jira-sync &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
  🔍 Dry Run — Preview of Jira issues to be created:
  📦 Epic: User Authentication
    📖 Story: As a new user, I want to register... &lt;span class="o"&gt;(&lt;/span&gt;5 SP&lt;span class="o"&gt;)&lt;/span&gt;
      ✏️  Task: Create user database model &lt;span class="o"&gt;(&lt;/span&gt;2h&lt;span class="o"&gt;)&lt;/span&gt;
      ✏️  Task: Build registration API endpoint &lt;span class="o"&gt;(&lt;/span&gt;4h&lt;span class="o"&gt;)&lt;/span&gt;
  ...
  Total: 4 epics, 9 stories, 25 tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cjp create &lt;span class="s2"&gt;"your idea"&lt;/span&gt;      &lt;span class="c"&gt;# 1. Generate plan with Copilot&lt;/span&gt;
cjp refine &lt;span class="s2"&gt;"add mobile app"&lt;/span&gt;  &lt;span class="c"&gt;# 2. Iterate and improve&lt;/span&gt;
cjp &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; csv      &lt;span class="c"&gt;# 3. Export for Jira import&lt;/span&gt;
cjp jira-sync                &lt;span class="c"&gt;# 4. Or push directly to Jira&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This entire project was built using GitHub Copilot CLI, and it played a dual role: it was both my &lt;strong&gt;development companion&lt;/strong&gt; throughout the build and the &lt;strong&gt;runtime AI engine&lt;/strong&gt; that powers the tool itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Learning Curve: From Confusion to Clarity
&lt;/h3&gt;

&lt;p&gt;I'll be honest — working with GitHub Copilot CLI effectively didn't happen overnight. It took several runs and iterations to thoroughly understand how to harness its full potential. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The early attempts were rough.&lt;/strong&gt; My first prompts were vague: "help me build a planning tool" or "create a CLI app." Copilot would give generic advice or boilerplate code that didn't quite fit. I quickly learned that Copilot CLI isn't a mind reader — it's a powerful tool that needs precise direction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The breakthrough came when I started treating Copilot CLI like a senior developer I was pair-programming with.&lt;/strong&gt; Instead of "build X," I learned to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Be specific about constraints&lt;/strong&gt;: "Build a TypeScript CLI using Commander.js that calls &lt;code&gt;copilot -sp&lt;/code&gt; and parses JSON responses"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Describe the context in detail&lt;/strong&gt;: "I need a function that extracts JSON from Copilot's output, but sometimes it wraps JSON in markdown code fences or adds explanatory text before/after"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break down complex requests&lt;/strong&gt;: Rather than "build the whole app," I'd ask for architecture first, then scaffolding, then specific implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;I also leveraged Copilot's agent capabilities extensively.&lt;/strong&gt; When I needed to understand the Jira API's Atlassian Document Format, I asked Copilot to act as a Jira API expert and explain the structure. When debugging parsing issues, I described the exact error case and asked it to propose robust extraction logic. Creating these focused "expert agents" in my prompts made Copilot's responses dramatically more useful.&lt;/p&gt;

&lt;p&gt;The turning point was realizing that &lt;strong&gt;the quality of Copilot's output is directly proportional to the detail you provide.&lt;/strong&gt; Once I started writing prompts that included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The exact tech stack and versions&lt;/li&gt;
&lt;li&gt;Sample input/output formats&lt;/li&gt;
&lt;li&gt;Edge cases to handle&lt;/li&gt;
&lt;li&gt;Constraints and requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...Copilot would generate production-ready code on the first try. What felt like a limitation at first — having to be so explicit — became a strength. It forced me to think through problems clearly before writing code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Meta Story: Copilot CLI Building a Copilot CLI Tool
&lt;/h3&gt;

&lt;p&gt;There's something beautifully recursive about using Copilot CLI to build a tool that wraps Copilot CLI. The key discovery was the &lt;code&gt;-sp&lt;/code&gt; flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-s&lt;/code&gt;&lt;/strong&gt; (script mode) — gives clean output without terminal UI chrome&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-p&lt;/code&gt;&lt;/strong&gt; (prompt mode) — non-interactive, single prompt in, response out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, &lt;code&gt;copilot -sp "your prompt"&lt;/code&gt; turns Copilot CLI into a programmable AI engine you can call from any application. No API keys, no OpenAI account — just an active Copilot subscription.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Copilot CLI Helped Build This Tool
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The meta twist:&lt;/strong&gt; I used Copilot CLI to build a tool that wraps Copilot CLI. The &lt;code&gt;copilot -sp&lt;/code&gt; (script mode, non-interactive prompt) flag was the key discovery — it lets you invoke Copilot programmatically and capture its structured output, making it perfect as an AI engine inside other CLI tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;During development, Copilot CLI helped me:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Architecture design&lt;/strong&gt; — I described the project idea to Copilot CLI and it helped me structure the TypeScript project, suggesting the command/lib/ui separation pattern&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jira API integration&lt;/strong&gt; — Copilot CLI walked me through the Jira REST API v3 document format (ADF), which saved hours of documentation reading&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt engineering&lt;/strong&gt; — I iterated on the planning prompt through Copilot CLI, testing different instructions to get reliable JSON output with proper Agile structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging&lt;/strong&gt; — When the JSON parsing broke on edge cases (code fences in responses, extra text), Copilot CLI helped me write the robust extraction logic&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Technical Integration
&lt;/h3&gt;

&lt;p&gt;The core innovation is using &lt;code&gt;copilot -sp&lt;/code&gt; as a programmatic AI engine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// From src/lib/planner.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;copilot&lt;/span&gt;&lt;span class="dl"&gt;'&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="s1"&gt;-sp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;maxBuffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;120000&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&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;p&gt;This approach means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No API keys needed&lt;/strong&gt; — just an active Copilot subscription&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% Copilot-native&lt;/strong&gt; — no OpenAI, no other AI providers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same AI that powers the coding agent&lt;/strong&gt; — you get the full power of Copilot's models&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The quality of the generated plans was consistently impressive. Copilot understood Agile methodology deeply — it wrote proper user stories ("As a... I want... So that..."), assigned realistic story points using the Fibonacci scale, estimated task durations sensibly, and even generated meaningful acceptance criteria. It felt like having a senior PM/scrum master on call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; with Commander.js for CLI framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; (&lt;code&gt;copilot -sp&lt;/code&gt;) as the AI engine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chalk + cli-table3 + Ora&lt;/strong&gt; for terminal UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Axios&lt;/strong&gt; for Jira REST API integration&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
  </channel>
</rss>
