VS Code - James Montemagno https://staging.montemagno.com/tag/vscode/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png VS Code - James Montemagno https://staging.montemagno.com/tag/vscode/ Hugo -- gohugo.io Tue, 13 Oct 2026 20:48:55 GMT 60 Introducing Oh My Posh Visual Configurator: Finally, a Drag-and-Drop Terminal Theme Builder! ✨ https://staging.montemagno.com/introducing-oh-my-posh-visual-configurator-finally-a-drag-and-drop-terminal-theme-builder/ 6952bf0593272a0001bc4431 Mon, 29 Dec 2025 19:43:35 GMT

If you've ever spent way too much time digging through JSON files trying to get your terminal prompt just right, this post is for you. I'm incredibly excited to share something I've been working on: the Oh My Posh Visual Configurator—a web-based drag-and-drop builder that makes creating beautiful terminal prompts actually fun (yes, really!).

The main interface showing the segment picker, configuration canvas, and live preview
The main interface showing the segment picker, configuration canvas, and live preview

The Problem We All Know Too Well

Let me be honest with you—I love Oh My Posh. It's hands down one of the best tools for customizing your terminal prompt across PowerShell, Bash, Zsh, Fish, and basically any shell you can think of. But here's the thing: configuring it has always meant diving into JSON, YAML, or TOML files and doing a lot of trial-and-error to get segments positioned correctly.

You know the drill:

  1. Edit the config file
  2. Save it
  3. Open a new terminal to see if it worked
  4. Realize the colors clash
  5. Go back to step 1
  6. Repeat for the next hour

There had to be a better way.

Enter the Visual Configurator

The Oh My Posh Visual Configurator solves this problem with a modern, intuitive web interface. No installation required—just open your browser and start building!

👉 Launch the Configurator

What Can You Do With It?

🎨 Browse 103+ Segments {#%F0%9F%8E%A8-browse-103-segments}

The left sidebar gives you access to every segment Oh My Posh supports, organized into logical categories:

  • System: Path, OS, Shell, Session, Battery, Time, Execution Time
  • Version Control: Git, Mercurial, SVN, Fossil, and more
  • Languages: Node.js, Python, Go, Rust, Java, .NET, PHP, Ruby... basically everything
  • Cloud & Infrastructure: AWS, Azure, GCP, Kubernetes, Docker, Terraform
  • CLI Tools: NPM, Yarn, Angular, React, Flutter
  • And more: Music players, health trackers, weather widgets
The Languages category expanded showing 26+ programming language segments
The Languages category expanded showing 26+ programming language segments

🖱️ Drag-and-Drop Interface {#%F0%9F%96%B1%EF%B8%8F-drag-and-drop-interface}

Just click a segment to add it to your prompt, or drag it exactly where you want it. Reordering is as simple as dragging segments around. Want to move that Git status before your path? Just drag it there!

Click any segment to customize its colors, style, and template
Click any segment to customize its colors, style, and template

⚡ Live Preview {#%E2%9A%A1-live-preview}

This is where it gets really cool. Every change you make shows up instantly in the preview panel at the bottom. Toggle between dark and light terminal backgrounds to make sure your theme looks great everywhere. The preview even renders powerline arrows and diamond shapes accurately!

🎛️ Full Customization {#%F0%9F%8E%9B%EF%B8%8F-full-customization}

Click any segment and the Properties Panel opens up with everything you need:

  • Style Selection: Powerline, Plain, Diamond, or Accordion
  • Color Pickers: Full hex color support for foreground and background
  • Template Editor: Customize exactly what each segment displays using Go templates
  • Block Settings: Configure prompt alignment, add new blocks, or create right-aligned prompts

📦 Import & Export {#%F0%9F%93%A6-import-export}

Already have an Oh My Posh config? Import it! The configurator supports JSON, YAML, and TOML formats. When you're done, export in whichever format you prefer and drop it right into your shell configuration.

Community Sharing 🤝 {#community-sharing-%F0%9F%A4%9D}

One of my favorite features is community sharing. Found the perfect configuration? Share it with everyone!

Browse official samples and community-contributed themes
Browse official samples and community-contributed themes
  1. Click the Share button in the header
  2. Fill in your theme details—name, description, tags
  3. Submit your configuration
  4. Your theme appears in the Community collection for others to use
Easy-to-use sharing dialog with step-by-step instructions
Easy-to-use sharing dialog with step-by-step instructions

This means you can browse themes created by other developers, try them instantly in the configurator, and tweak them to match your style. The community grows together!

Under the Hood: Some Fun Architecture Decisions 🏗️ {#under-the-hood-some-fun-architecture-decisions-%F0%9F%8F%97%EF%B8%8F}

For my fellow developers who enjoy the technical details, here's what's powering this thing:

React 19 + TypeScript + Vite

I went with the latest React 19 for this project, paired with TypeScript for type safety (trust me, when you're dealing with complex configuration objects, types are your friend). Vite provides blazing-fast builds and hot module replacement that makes development a joy.

@dnd-kit for Drag-and-Drop

After evaluating several drag-and-drop libraries, @dnd-kit won out. It's modern, accessible, performant, and plays nicely with React 18+. The sortable preset made implementing segment reordering straightforward, and it handles edge cases like keyboard navigation out of the box.

Zustand for State Management

I'm a big fan of Zustand for state management. It's lightweight, has zero boilerplate, and the persistence middleware lets me save your configuration to localStorage automatically. Your work is never lost!

// Simplified example of our store structure
const useConfigStore = create(
  persist(
    (set) => ({
      config: defaultConfig,
      addSegment: (blockId, segment) => set((state) => /* ... */),
      updateSegment: (blockId, segmentId, updates) => set((state) => /* ... */),
      // ...
    }),
    { name: 'ohmyposh-config' }
  )
)

Dynamic Segment Loading

With 103+ segments, loading everything upfront would be wasteful. Instead, segment metadata lives in separate JSON files by category (public/segments/*.json), loaded on demand when you expand a category. This keeps the initial bundle small and the UI snappy.

Tailwind CSS 4.1

Styling is handled by Tailwind CSS 4.1, which gives us:

  • Consistent design tokens
  • Dark theme by default (it's a terminal tool after all!)
  • Rapid iteration on UI polish
  • Small production bundles through automatic purging

100% Client-Side

Your configurations never leave your browser. Everything runs locally—no backend servers, no data collection, no privacy concerns. Export your config and it's yours forever.

Built with GitHub Copilot & VS Code

Here is what blows my mind about this app is that I built it in under an hour. I started by jotting down a product requirements doc in the GitHub mobile app using Copilot, based on a simple idea. Then I created an issue, assigned it to Copilot, and went to bed. By the next morning, I had a working prototype! I spent about 50 minutes in VS Code adding features like community feeds and cleaning up the code for future updates. Copilot even set up all the GitHub Actions workflows and deployed everything to GitHub Pages in seconds. Turning an idea into a live app in just hours—something that used to take me weeks—is absolutely incredible.

Getting Started in 30 Seconds

  1. Open the app: https://jamesmontemagno.github.io/ohmyposh-configurator/
  2. Add segments: Click segments from the left sidebar or drag them to the canvas
  3. Customize: Click any segment to adjust colors, templates, and styles
  4. Preview: Watch your prompt update in real-time at the bottom
  5. Export: Choose JSON, YAML, or TOML and download your configuration
  6. Apply it:

# PowerShell oh-my-posh init pwsh --config ~/your-theme.json | Invoke-Expression

# Bash eval "$(oh-my-posh init bash --config ~/your-theme.json)"

# Zsh eval "$(oh-my-posh init zsh --config ~/your-theme.json)"

That's it! You've got a beautiful, custom terminal prompt.

Sample Configurations to Get You Started

Not sure where to begin? We've included 6 professional sample configurations:

  • Minimal: Clean and simple
  • Developer: Language-aware with Git integration
  • DevOps: Cloud and Kubernetes focused
  • Full Featured: All the bells and whistles
  • Powerline Classic: Traditional powerline style
  • Diamond Style: Rounded segment separators
Community-contributed themes available in the Theme Library
Community-contributed themes available in the Theme Library

Load any of these from the Sample Picker and customize from there!

What's Next?

I'm really excited about where this project can go. Some ideas on the roadmap:

  • More starter templates based on community feedback
  • Theme galleries curated by the community
  • Advanced template editor with autocomplete
  • PWA support for offline use
  • Keyboard shortcuts for power users

Try It Out and Let Me Know!

I'd love to hear what you think. Give it a spin at https://jamesmontemagno.github.io/ohmyposh-configurator/ and let me know how it goes!

Found a bug? Have a feature request? Open an issue on GitHub.

Created an awesome theme? Share it with the community using the Share button!

Happy coding, and may your terminal always look beautiful! 🚀


This blog was drafted with GitHub Copilot and Claude Sonnet 4.5 based off previous blogs. Screenshots were taken with the Playwright MCP server using the cloud agent completely autonomously. I reviewed this blog post and tweaked it as necessary.

]]>
Building a Complete FIRE Calculator App with GitHub Copilot in One Chat Session https://staging.montemagno.com/building-a-complete-fire-calculator-app-with-github-copilot-in-one-chat-session/ 694b62804480ae000170634b Wed, 24 Dec 2025 16:13:01 GMT

I've been diving deep into financial independence planning lately, and as a developer, I naturally wanted a tool that does exactly what I need—without the clutter, ads, or privacy concerns of existing calculators out there. So I decided to build one from scratch using GitHub Copilot's agent mode in VS Code. What started as a simple "let's see what happens" experiment turned into a fully-featured, privacy-first PWA with 9 different calculators, all built in a single conversational chat session in about 30 minutes.

The Starting Point

I had a clear vision: a FIRE (Financial Independence, Retire Early) calculator that respects user privacy. No cookies, no analytics, no data leaving the browser. Just pure client-side calculations with the ability to share scenarios via URL parameters.

My initial prompt was straightforward leveraging the plan agent in VS Code:

"I want to build a financial independence calculator app. It should be a React + TypeScript PWA with Tailwind CSS, dark mode support, and work completely offline. Privacy is key—no data storage, no analytics."

The plan agent got to work asking me questions along the way until it had the context it needed and I answered enough questions that I felt good about it getting to work. From there, Copilot scaffolded the entire project structure: Vite config, TypeScript setup, Tailwind with a custom "fire" orange color palette, and even service worker configuration for offline support. Within minutes I had a running dev server.

Iterating Through Features

What I love about working with Copilot in agent mode is the conversational flow. I didn't have to context-switch between planning and implementing. Each feature request built naturally on the previous one.

The Core Calculators

I started with the Standard FIRE calculator—the classic "25x your annual expenses" rule. Copilot generated not just the calculation logic but also:

  • Responsive input components with tooltips explaining each field
  • A beautiful projection chart using Recharts
  • Real-time URL parameter syncing so users can bookmark or share their scenarios
  • Result cards with the key metrics highlighted

Then came the variations:

"Now add a Coast FIRE calculator. Same structure but with the specific Coast FIRE math—how much do you need saved NOW so compound growth does the rest."

"Let's add Lean FIRE (≤$40k expenses) and Fat FIRE ($100k+ expenses) with appropriate warnings and lifestyle tips."

"Add a Barista FIRE calculator that factors in part-time income."

Each calculator maintained consistent styling while having its own personality—different color schemes, contextual explanations, and tailored result displays.

The Fun Additions

Halfway through, I asked for three more calculators that I hadn't seen done well elsewhere:

"Add these: 1) Savings Rate calculator that shows how your savings rate impacts years to FIRE, 2) Reverse FIRE that works backwards from a target retirement age, 3) Healthcare Gap calculator for estimating costs between early retirement and Medicare."

Copilot handled the math, the UI, and even added helpful reference tables and scenario comparisons. The Healthcare Gap calculator includes ACA subsidy considerations and strategies like health sharing ministries and Barista FIRE for benefits.

Real-Time Bug Fixes and Refinements

This is where the conversation got interesting. I noticed the Coast FIRE progress card was showing "2160%" instead of "21.5%". A quick:

"The Coast FIRE current progress card is showing an extremely high number—double check those calculations."

Copilot traced through the code and found the issue: the percentage was being multiplied by 100 twice—once in the calculation and again in the ResultCard's percent formatter. Fixed in seconds.

Another issue: the age input would snap to 18 whenever you tried to clear it to type a new value. Annoying UX.

"Entering the retirement age is weird because it sets it to 18 when I try to clear it out. Just don't calculate if invalid but allow entry."

The fix added local state management so users can freely type without the input fighting back, with validation only on blur.

Privacy and Polish

I asked for disclaimers on every page—this isn't financial advice, results are hypothetical, consult a professional. Copilot created a reusable Disclaimer component and added it to all 10 pages in one pass.

The app includes:

  • No cookies or localStorage - Your financial data never leaves your browser
  • No analytics - Zero tracking scripts, no Google Analytics
  • URL-based sharing - Save calculations in the URL, bookmark or share as you choose
  • Offline-first PWA - Works without internet after first load
  • Open source - All code available on GitHub for transparency

Quality of Life Features

Throughout the session, I kept adding small enhancements:

"Add a monthly/annual toggle to the contribution and expenses inputs."

"Put a progress bar showing how far along you are toward your FIRE number."

"Add milestone lines at 25%, 50%, 75% on the projection charts."

"Quick preset buttons for common scenarios—conservative, moderate, aggressive."

Each request was implemented cleanly, maintaining the existing code style and patterns.

The Tech Stack

For those interested in the technical details:

  • Vite + React 18 with TypeScript
  • Tailwind CSS with custom fire-orange color palette
  • Recharts for interactive projection graphs
  • React Router for navigation with URL parameter persistence
  • Vite PWA Plugin for service worker and offline support
  • GitHub Pages for hosting

The entire codebase is well-organized:

src/
  components/
    charts/      # Recharts wrappers
    inputs/      # CurrencyInput, PercentageInput, AgeInput
    ui/          # Cards, Buttons, ProgressBar, Disclaimer
  pages/         # Each calculator as a page component
  hooks/         # useCalculatorParams for URL sync
  utils/         # All the FIRE math calculations

Key Takeaways

Conversational development works. Instead of writing detailed specs upfront, I could explore ideas naturally. "What if we also showed..." or "Actually, can you change that to..." kept the momentum going.

Copilot handles the boring stuff. Adding disclaimers to 10 pages? Tedious. Watching Copilot do it correctly in one multi-file edit? Satisfying.

Bugs get fixed in context. When something didn't work right, I could describe the symptom in plain English and Copilot would trace through the logic to find the root cause.

The result is production-ready. This isn't a prototype or demo—it's a real app I'm actually using to plan my own financial future.

Try It Yourself

The app is live at https://myfirenumber.com and the source is on GitHub.

All 9 calculators are there:

Calculator What it does
🎯 Standard FIRE Classic 25x expenses rule
⛵ Coast FIRE How much you need now so growth does the rest
🌿 Lean FIRE FI with minimalist lifestyle (≤$40k/year)
💎 Fat FIRE FI without compromising ($100k+/year)
☕ Barista FIRE Part-time work + portfolio income
📊 Withdrawal Rate Test portfolio longevity at different rates
🧮 Savings Rate How savings rate impacts time to FIRE
🔄 Reverse FIRE Work backwards from target retirement age
🏥 Healthcare Gap Costs between early retirement and Medicare

Play with the parameters, bookmark your scenarios, and let me know what you think. And if you're curious about building your own apps with Copilot agent mode, just start a conversation—you might be surprised how far it takes you.


This blog was written with VS Code and Claude Sonnet 4.5 based on a conversational chat session. I also reviewed and slightly modified the content.

]]>
Building Better Apps with GitHub Copilot Custom Agents https://staging.montemagno.com/building-better-apps-with-github-copilot-custom-agents/ 69078e67ebf2b1000161ff74 Sun, 02 Nov 2025 17:36:04 GMT

When building Hotkey Typer, a Windows Forms app that types predefined snippets via hotkey, I discovered the power of GitHub Copilot's new custom agents feature. What started as a simple refactoring request turned into an eye-opening demonstration of how specialized AI agents can dramatically improve code quality and implementation speed.

What Are Custom Agents?

Custom agents are specialized versions of GitHub Copilot coding agent that you can tailor to your unique workflows, coding conventions, and use cases. Instead of repeatedly providing the same instructions and context, custom agents allow you to define specialized agents that act like tailored teammates—following your standards, using the right tools, and implementing team-specific practices.

Think of custom agents as expert consultants embedded directly in your development workflow. They're defined using simple Markdown files (called agent profiles) that specify:

  • Name and description: What the agent specializes in
  • Custom prompts: Detailed instructions that define the agent's behavior and expertise
  • Tools: Specific tools the agent can access (optional)
  • MCP servers: Model Context Protocol server configurations for enhancing agents

Where You Can Use Custom Agents

Once created, custom agents are available wherever you use Copilot coding agent:

  • GitHub.com: In the agents tab, panels, issue assignments, and pull requests
  • Visual Studio Code: As chat modes in the editor
  • GitHub Copilot CLI: Command-line interactions

Each interaction maintains consistency based on the agent's defined profile, ensuring targeted support tailored to your specific needs.

Screenshot 2025-11-02 at 9.32.11 AM.png

Where to Configure Custom Agents

You can define agent profiles at different levels:

  • Repository level: Place .md files in .github/agents/ for project-specific agents
  • Organization level: For broader team availability
  • Enterprise level: For company-wide standardization

The agent profile format is straightforward:

---
name: readme-creator
description: Agent specializing in creating and improving README files
---

You are a documentation specialist focused on README files. Your scope is limited to
README files or other related documentation files only - do not modify or analyze code files.

Focus on the following instructions:
- Create and update README.md files with clear project descriptions
- Structure README sections logically: overview, installation, usage, contributing
- Write scannable content with proper headings and formatting
- Add appropriate badges, links, and navigation elements

Discovering the WinForms Expert Agent

The real power of custom agents became apparent when I discovered the awesome-copilot repository, a curated collection of custom agents maintained by GitHub. This repository contains specialized agents for various frameworks and technologies, including C#, WinForms, arm Migration, Dynatrace, LaunchDarkly, Neon, PagerDuty, and more!

Among these gems, I found the WinForms Expert agent—a sophisticated agent specifically designed for .NET Windows Forms development. This agent encodes decades of WinForms best practices into a single, reusable profile.

What Makes the WinForms Expert Special?

The WinForms Expert agent is a comprehensive guide that understands the nuanced challenges of WinForms development. It addresses several critical areas:

Designer Code vs. Regular Code: One of WinForms' unique challenges is managing two distinct code contexts—designer-generated serialization code and modern business logic. The agent knows exactly which C# features are allowed in each context.

Modern .NET Patterns: The agent is fully updated for .NET 8-10, including:

  • MVVM data binding patterns with the Community Toolkit
  • Async/await patterns with proper InvokeAsync overload selection
  • DarkMode support and high-DPI awareness
  • Nullable reference types (NRTs) in the right places

Layout Best Practices: Comprehensive guidance on using TableLayoutPanel and FlowLayoutPanel for responsive, DPI-aware layouts that work across different screen sizes and scaling factors.

CodeDOM Serialization Management: Critical rules for property serialization in the WinForms designer, preventing common pitfalls with [DefaultValue] attributes and ShouldSerialize*() methods.

Exception Handling: Proper patterns for async event handlers and application-level exception handling to prevent process crashes.

The agent's instructions are remarkably detailed, covering everything from control naming conventions to accessibility requirements. It's like having a senior WinForms architect reviewing every line of code.

Adding the WinForms Expert to My Repository

Adding a custom agent from the awesome-copilot repository is remarkably simple:

  1. Create the .github/agents/ directory in your repository
  2. Copy the agent profile (a .md file) into this directory
  3. Commit and push—that's it!

For Hotkey Typer, I copied the WinFormsExpert.agent.md file into .github/agents/, making it immediately available to Copilot throughout my repository.

The Real-World Test: Multiple Snippets Feature

I had opened Issue #3 requesting a new feature: support for managing multiple reusable text snippets instead of just a single predefined block. Users needed to switch between different prompts, code templates, and demo scripts quickly without manual settings editing.

The feature requirements included:

  • Maintain a list of snippets with names and content
  • Select active snippet from a dropdown in the main UI
  • New/Copy/Rename/Delete operations with validation
  • Backward-compatible migration from the old single-text format
  • Persist everything in settings.json

First Attempt: Without the Custom Agent (PR #7)

I first assigned the standard Copilot coding agent to Issue #3, resulting in Pull Request #7. The implementation was functional:

  • ✅ Data model created with Snippet class
  • ✅ CRUD operations implemented
  • ✅ UI with ComboBox and management buttons
  • ✅ Unit tests added
  • ✅ Settings serialization worked

However, there were notable issues:

  • Layout wasn't optimal for WinForms best practices
  • Controls weren't properly anchored/docked for responsive resizing
  • Missing some WinForms-specific patterns for dialog handling
  • Code style didn't fully align with established WinForms conventions
  • No consideration for DPI scaling or accessibility

While functional, it felt like code written by someone proficient in general C# but not deeply experienced with WinForms specifics.

Second Attempt: With the WinForms Expert Agent (PR #8)

Then I closed PR #7 and reassigned Issue #3 to Copilot, but this time explicitly mentioning the WinForms Expert agent. The results in Pull Request #8 were dramatically better:

Improved UI Organization:

Snippet: [────────Dropdown (300px)────────▼]
         [New] [Copy] [Rename] [Delete]

[Text Editor (460x135)]

[Speed slider, checkboxes, file options]

[Save]
[Minimize] [Stop]        Status: Active

The agent reorganized the layout following WinForms best practices:

  • Logical grouping of snippet management operations
  • Proper spacing and margins (3px minimum)
  • Controls properly anchored for responsive behavior
  • Consideration for DPI scaling

Enhanced User Experience:

  • Popup dialogs using InputDialog for New/Copy/Rename operations
  • Proper validation with meaningful error messages
  • Case-insensitive duplicate detection
  • Protection against deleting the last snippet
  • Better visual feedback for operations

Code Quality Improvements:

  • Modern C# 11-14 features in business logic
  • Proper separation between designer code and regular code
  • File-scoped namespaces
  • Target-typed new expressions
  • Nullable reference types in appropriate contexts
  • Exception handling with ArgumentNullException.ThrowIfNull

Even Better Documentation: The agent included detailed diagrams of the UI layout directly in the PR description, making the implementation immediately understandable.

Key Code Differences: Before and After

Let me show you some concrete examples of the improvements the WinForms Expert agent made:

1. InputDialog Helper Class

PR #7 (Without WinForms Expert): Used an inline dialog creation pattern with repetitive code in each button handler.

PR #8 (With WinForms Expert): Created a dedicated, reusable InputDialog class following WinForms best practices:

internal class InputDialog : Form
{
    private readonly TextBox txtInput;
    private readonly Button btnOK;
    private readonly Button btnCancel;

    public string InputText => txtInput.Text;

    public InputDialog(string prompt, string title, string defaultValue = "")
    {
        Text = title;
        FormBorderStyle = FormBorderStyle.FixedDialog;
        StartPosition = FormStartPosition.CenterParent;
        MaximizeBox = false;
        MinimizeBox = false;
        ClientSize = new Size(350, 120);

        // Control setup...

        // Select all text when dialog opens
        Load += (s, e) => txtInput.SelectAll();
    }

    public static string? Show(string prompt, string title, string defaultValue = "")
    {
        using var dialog = new InputDialog(prompt, title, defaultValue);
        return dialog.ShowDialog() == DialogResult.OK ? dialog.InputText : null;
    }
}

This is a textbook WinForms pattern: proper disposal with using, nullable return type, static factory method, and proper dialog configuration.

2. Settings Migration Pattern

PR #7 (Without WinForms Expert): Used a "fresh start" approach that ignored existing settings if loading failed.

PR #8 (With WinForms Expert): Implemented proper backward-compatible migration:

// Migration: Convert old single PredefinedText to snippet if no snippets exist
if (settings.Snippets == null || settings.Snippets.Count == 0)
{
    string contentToMigrate = !string.IsNullOrEmpty(settings.PredefinedText)
        ? settings.PredefinedText
        : DefaultSnippetContent;
    snippets = new List<TextSnippet>
    {
        new TextSnippet
        {
            Id = DefaultSnippetId,
            Name = DefaultSnippetName,
            Content = contentToMigrate,
            LastUsed = DateTime.Now
        }
    };
    activeSnippetId = DefaultSnippetId;
}
else
{
    snippets = settings.Snippets;
    activeSnippetId = settings.ActiveSnippetId;

    // Validate active snippet exists
    if (string.IsNullOrEmpty(activeSnippetId) ||
        !snippets.Any(s => s.Id == activeSnippetId))
    {
        activeSnippetId = snippets.FirstOrDefault()?.Id;
    }
}

This handles the upgrade path gracefully, preserving user data instead of discarding it.

3. UI Layout in Designer Code

PR #7 (Without WinForms Expert): Controls placed with absolute positioning and cramped spacing:

var btnNewSnippet = new Button
{
    Text = "New",
    Location = new Point(335, 82),
    Size = new Size(35, 25),  // Cramped button
    Font = new Font("Segoe UI", 8F)
};

PR #8 (With WinForms Expert): Better organized with logical grouping and proper sizing:

// Snippet selector ComboBox - wider, more prominent
var cmbSnippets = new ComboBox
{
    Name = "cmbSnippets",
    Location = new Point(85, 82),
    Size = new Size(300, 23),  // 300px width for readability
    DropDownStyle = ComboBoxStyle.DropDownList,
    Font = new Font("Segoe UI", 9F)
};

// Snippet management buttons - moved under dropdown for logical grouping
var btnNewSnippet = new Button
{
    Name = "btnNewSnippet",
    Text = "New",
    Location = new Point(85, 110),
    Size = new Size(70, 25),  // Proper button size
    Font = new Font("Segoe UI", 9F)
};

The WinForms Expert agent understood that:

  • ComboBoxes should be wide enough to display meaningful names
  • Related buttons should be grouped together visually
  • Font size 8F is too small for modern displays
  • Controls need descriptive names for maintainability

4. Validation Logic with User Feedback

PR #7: Basic validation without proper user feedback:

if (string.IsNullOrWhiteSpace(name)) return;
if (snippets.Any(s => s.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))
{
    MessageBox.Show("A snippet with this name already exists.",
        "Duplicate Name", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    return;
}

PR #8: Enhanced validation with trim and separate empty-string check:

// Validate: trim and check uniqueness (case-insensitive)
name = name.Trim();
if (string.IsNullOrEmpty(name))
{
    MessageBox.Show("Snippet name cannot be empty.",
        "Invalid Name", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    return;
}

if (snippets.Any(s => string.Equals(s.Name, name, StringComparison.OrdinalIgnoreCase)))
{
    MessageBox.Show("A snippet with this name already exists.",
        "Duplicate Name", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    return;
}

The WinForms Expert understood the importance of:

  • Trimming user input (common WinForms pattern)
  • Providing specific error messages for different failure modes
  • Using string.Equals for clarity over extension method

5. Modern C# Features in Business Logic

PR #8 consistently used modern C# patterns throughout:

// File-scoped namespace
namespace HotkeyTyper;

// Target-typed new
private List<TextSnippet> snippets = new();

// Expression-bodied member
public string InputText => txtInput.Text;

// Nullable reference types
public static string? Show(string prompt, string title, string defaultValue = "")

// Using declaration (proper disposal)
using var dialog = new InputDialog(prompt, title, defaultValue);

While PR #7 had some modern features, PR #8 applied them consistently and appropriately.

6. Comprehensive Unit Tests

PR #8 included thorough migration tests that PR #7 lacked:

[Fact]
public void OldSettings_MigratesToSnippets()
{
    // Arrange - Old settings format with single PredefinedText
    string oldSettingsJson = """
    {
        "PredefinedText": "Hello, World!",
        "TypingSpeed": 7,
        "HasCode": true
    }
    """;

    var oldSettings = JsonSerializer.Deserialize<AppSettings>(oldSettingsJson);

    // Act & Assert - Settings should be migrated
    Assert.NotNull(oldSettings);
    Assert.Null(oldSettings.Snippets);
    Assert.Equal("Hello, World!", oldSettings.PredefinedText);
}

These tests ensure the backward compatibility works correctly—a crucial detail for production applications.

The Visible Difference

The before-and-after images tell the story:

Without WinForms Expert:

  • Basic layout, functional but not polished
  • Controls not optimally positioned
  • Missing WinForms-specific refinements

With WinForms Expert:

  • Clean, logical organization
  • Professional spacing and alignment
  • Proper control grouping
  • Responsive layout that scales correctly

The agent even provided visual diagrams showing the layout structure, demonstrating deep understanding of WinForms design patterns.

The Impact: Quality and Velocity

The difference between PR #7 and PR #8 wasn't just cosmetic. The WinForms Expert agent delivered:

Better Architecture:

  • Proper use of BindingSource patterns for data binding
  • Correct designer code serialization patterns
  • Appropriate use of modern C# features in the right contexts
  • Following established WinForms conventions consistently

Fewer Iterations:

  • PR #7 required multiple rounds of feedback and corrections
  • PR #8 was nearly perfect on the first attempt
  • Code reviews focused on business logic, not framework usage

Knowledge Transfer:

  • Seeing the agent's implementation taught me WinForms patterns I hadn't fully mastered
  • Comments in the code explained why certain approaches were used
  • The detailed PR descriptions served as documentation

Time Savings:

  • What would have taken days of iteration took hours
  • Less time debugging designer code issues
  • More time focusing on features, not framework quirks

Getting Started with Custom Agents

Ready to try custom agents in your projects? Here's how:

1. Explore the Awesome-Copilot Repository

Visit github.com/github/awesome-copilot and browse the available agents.

2. Add an Agent to Your Repository

  1. Create .github/agents/ in your repository
  2. Copy the agent .md file from awesome-copilot
  3. Customize if needed (optional)
  4. Commit and push

3. Use the Agent

In GitHub issues, pull requests, or VS Code:

  • Mention the agent by name in your request
  • For issues: Assign Copilot and reference the agent
  • For VS Code: Use <agent-name> in chat from agent drop down

Screenshot 2025-11-02 at 9.33.00 AM.png

4. Create Your Own Agents

Have specific team conventions? Create custom agents that encode:

  • Your coding standards
  • Framework-specific patterns
  • Architecture preferences
  • Testing strategies
  • Documentation requirements

Full documentation: GitHub Docs - Creating Custom Agents

Key Takeaways

Working with the WinForms Expert agent taught me several valuable lessons:

Specialization Matters: Generic AI coding assistance is good, but specialized agents that understand framework-specific patterns are transformative. The depth of knowledge in the WinForms Expert agent far exceeded what I could convey in ad-hoc prompts.

Consistency Across the Team: Custom agents ensure everyone on your team follows the same patterns and best practices, even for developers less familiar with specific frameworks.

Living Documentation: Agent profiles serve as executable documentation of your team's coding standards—they don't just describe patterns, they enforce them.

Knowledge Amplification: Using specialized agents is a learning experience. Seeing high-quality, pattern-consistent code generated repeatedly helps developers internalize best practices.

Velocity Without Sacrificing Quality: The right custom agent doesn't just generate code faster—it generates better code faster, reducing technical debt and future maintenance burden.

Wrapping Up

The difference between PR #7 (without custom agent) and PR #8 (with WinForms Expert) perfectly illustrates why custom agents represent a significant leap forward in AI-assisted development. It's not about replacing developer expertise—it's about amplifying it with domain-specific knowledge that would otherwise require years of experience to accumulate.

For Hotkey Typer, the WinForms Expert agent helped deliver a feature that not only works but follows industry best practices, is maintainable, accessible, and properly architected for future enhancements. The implementation handles edge cases, uses appropriate design patterns, and would pass a senior code review with minimal comments.

If you're working with WinForms—or any specialized framework—I highly recommend exploring custom agents. The awesome-copilot repository is an excellent starting point, and creating your own team-specific agents is easier than you might think.

Learn More

Custom agents aren't just the future of AI-assisted development—they're available today, and they're already making a significant difference in how we build software. Give them a try, and see the difference specialized expertise can make in your projects!


Have you tried custom agents in your projects? I'd love to hear about your experiences. Share your thoughts and questions on X!

This blog was written with VS Code and Claude Sonnet 4.5 based on a very lovely prompt with images, MCP server access, and more written by ME! I also reviewed and slightly modified the blog.

]]>
5 Ways I Use Background Coding Agents Every Day https://staging.montemagno.com/5-ways-i-use-background-coding-agents-every-day/ 68d814b64825cf00016b2e62 Wed, 01 Oct 2025 17:46:09 GMT

Coding agents are different from in-editor chat and agent modes for AI assisted programming. They run asynchronously—often in the cloud—tackling tasks while you focus locally. I rely heavily on the GitHub Copilot coding agent and its VS Code integration to spin up multiple parallel workflows. Below are five everyday patterns I use to offload work, speed up development, and keep my repos in top shape.


1. Assign Issues Directly to GitHub Copilot

When a new issue or idea lands, I immediately hand it off to Copilot so it can start coding while I tackle higher-level planning or work on any tasks. I have worked on huge issues, small bugs, and complete re-designs with this flow. What is great is that you can give it a lot of context in the issue to help guide it along. You can see everything directly in VS Code, stop it, ask it for changes, and even get a diff view without leaving the code editor.

By assigning an issue to the coding agent:

  • Checks out the base branch (usually main) and creates a feature branch named after your issue.
  • It installs dependencies, runs any setup workflows, and begins implementing the requested feature or fix.
  • A pull request pops up automatically, complete with commit history, a description of what was done, and live session logs you can follow.
  • I can review diffs right in VS Code’s Agent sessions view or directly on GitHub before merging.

Key benefits:

  • Parallelize work: start multiple issues at once without context-switching overhead.
  • Instant feedback: see what Copilot built, ask follow-up questions in the same session.
  • Consistency: every branch follows your CI/CD and code-style rules from day one.

Easy setup:

Learn more: • GitHub Copilot Coding Assistant overview: https://docs.github.com/en/copilot/concepts/agents/coding-agent • VS Code integration with GitHub Pull Requests & Issues: https://code.visualstudio.com/docs/copilot/copilot-coding-agent


2. Delegate Ad-Hoc Tasks from VS Code Chats

Spotted an improvement in your code or UI? Instead of stopping to implement it, or open an issues, you can simply delegate from your chat panel or from GitHub.com and get back to flow. This is maybe one of my favorite ways to use coding agents as I can even spin up a

How it works:

  • In VS Code, open Chat Sessions (enable via Settings > Chat: Agent Sessions View Location and set to view).
  • Under
  • Type a request like “When user clicks Hacker News, auto-load articles in content-feed.” or whatever else you want it to do. You can even reference files and documents.
  • Click Delegate to coding agent send button —Copilot spins up a background session, generates code, and opens a pull request.
  • Monitor progress in the Chat Sessions view or jump into the PR on GitHub.

Why I love it:

  • Lightweight delegation and works of a specific branch that you choose.
  • Rich context: chat history and your codebase give Copilot full visibility.
  • Notification-driven: get pinged when the PR is ready, so you only interrupt flow once.

Tip: You can also trigger these tasks from the mobile apps, GitHub.com on your repo, or the Copilot dashboard at https://github.com/copilot/agents without hopping into each repo.


3. Continue Work Across Branches and Chat Sessions

Sometimes I am working on a bug or new features and I have it half-implemented locally. Or sometimes I ideate in Ask mode and don't really want to open up an issue or work on it right now. Well, you can simply push your local changes and chat context into a new agent session so Copilot can finish while you move on.

Step by step:

  1. On your feature branch (or main), start a Copilot chat to outline next steps (e.g., add docs, refactor helpers).
  2. Make local edits but don’t commit everything.
  3. Click Delegate to coding agent, choose Include changes, and let Copilot fork a sibling branch with your pending code.
  4. Copilot completes the work—documentation, tests, cleanup—and issues a pull request ready for review.

Advantages:

  • Seamless handoff: your uncommitted work becomes the starting point for the agent.
  • Branch-of-branch workflow: keep your main branches tidy while Copilot wraps up.
  • No more “oh right, I forgot to finish that” moments—wake up to a completed PR.

4. Iterate on Pull Requests with Interactive Comments

When I work with the coding agents it isn't always going to get it right the first time. Sometimes it is the coding agent, sometimes it is because I didn't give it enough context, and sometimes I just ended up wanting it a bit different . I like to treat Copilot like a teammate and file a review comment and then watch it push fixes in real time.

Workflow:

  • Open a PR that Copilot has been working on in GitHub or in the chat sessions in VS Code and comment @copilot with error messages or changes you want.
  • Copilot launches a new agent session, applies fixes or enhancements, and updates the same branch.
  • You can reply to the agent’s comments, request tweaks, or approve and merge when satisfied.

Perks:

  • Instant turn-around on feedback.
  • Team-like collaboration: follow the same comment-reply flow you’d use with a colleague (or yourself in my case often).
  • Full history: every change is tracked in the PR conversation and commit log.

Docs to explore: • Using Copilot in pull requests: https://docs.github.com/en/copilot/extend-your-editor-with-copilot-chat#use-copilot-in-pull-requests


5. Keep Dependencies Secure and Up-to-Date with Dependabot

Dependabot isn’t AI-driven, but it embodies the same “background agent” principle. It quietly opens PRs to bump libraries and fix vulnerabilities.

Setup highlights:

  • In your GitHub repos Settings > Security > Advanced Secuirty, enable Dependency graph, Dependabot alerts, and Dependabot security updates.
  • Create a .github/dependabot.yml to specify package ecosystems (npm, NuGet, etc.), directory paths, and update schedules.
  • Dependabot will open pull requests whenever a new version is available or a security issue is discovered.
  • Review, merge, or auto-merge based on your repo’s policies.

Why it matters:

  • You don’t have to remember every library you depend on—they get updated for you.
  • Security vulnerabilities get flagged and patched without manual intervention.
  • Your CI/CD stays green with minimal overhead.

Get started: https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically


Setting Up Your Environment for Background Coding Agents

Before you reap these benefits, configure both GitHub and your local IDE:

  1. Enable the Copilot Coding Agent
  2. Install VS Code Extensions
  3. Activate Chat & Agent Sessions
    • In VS Code Settings, search “Agent Sessions View Location” and switch from Disabled to View.
    • This adds the Chat Sessions icon for monitoring all local and active background tasks.
  4. Add Copilot Setup Workflows (optional but recommended)
  5. Configure Dependabot
    • Add a .github/dependabot.yml specifying ecosystems, directories, and schedules.
    • Enable security updates and auto-merge rules under Settings > Advanced Security.

With those pieces in place, you’ll have a fleet of coding agents— GitHub Copilot and Dependabot—working around the clock to keep your code moving forward.


How are you leveraging background agents in your workflow? Hit me on X or leave a comment on YouTube and let me know.

]]>
Announcing Hotkey Typer — type long prompts with a hotkey https://staging.montemagno.com/announcing-hotkey-typer/ 68d715b04825cf00016b2592 Fri, 26 Sep 2025 22:57:22 GMT When I'm recording demos or making videos I often need to reproduce long prompts or blocks of text on-screen. Manually retyping them every time is slow and error-prone, and pasting from the clipboard can feel jerky and reveal private content. I wanted a tiny, reliable app that would let me press a global hotkey and have the application type a predefined, human-like block of text into whatever app currently has focus — perfect for demos, tutorials, and repeatable workflows.

Enter Hotkey Typer: a small Windows Forms utility that types back long prompts using a single global hotkey.

What Hotkey Typer does

  • Register a global hotkey (defaults to CTRL+SHIFT+1) that works across applications
  • Type a predefined text snippet into the currently focused window with human-like timing
  • Save your snippet and typing speed to a settings.json file for persistence
  • Minimize to the system tray so it runs unobtrusively in the background

This is intentionally minimal — it solves one problem very well: quickly and reliably retyping long prompts during recordings.

Quick feature tour

  • Global hotkey: Press CTRL+SHIFT+1 from any running application to trigger typing.
  • Human-like typing: Characters are sent one-by-one with randomized delays so the result looks natural on screen.
  • Typing speed slider: Choose from Very Slow through Very Fast (1–10) to simulate different typing paces.
  • Persistent settings: Your text and speed are saved to settings.json in the app directory.
  • System tray: Minimize the UI and keep the app running in the tray with a context menu to show or exit.

How I built it (and how GitHub Copilot + VS Code helped)

This little app was built as a Windows Forms app targeting .NET 10. I used Visual Studio Code as my editor and relied on GitHub Copilot to accelerate routine code — generating method bodies, serialization snippets, and the interop signatures for the Windows API calls.

Why Copilot was helpful here:

  • Saved time writing boilerplate: form initialization, settings load/save, and JSON serialization were scaffolded quickly.
  • Suggested idiomatic C# snippets: small things like the randomized delay logic and the speed-to-label mapping were easier to iterate on.
  • Encouraged small, testable functions: I split concerns into LoadSettings/SaveSettings, InitializeSystemTray, TypePredefinedText, and so on.

I used VS Code for quick editing and testing, and dotnet CLI for building and running the app.

How to build and run

Clone the repo and run it with the .NET SDK installed (Windows 10+):

git clone https://github.com/jamesmontemagno/app-hotkeytyper.git
cd app-hotkeytyper/HotkeyTyper
dotnet build
dotnet run

The app will start and register the default hotkey. Enter your desired text, click Update Text, then switch to any application and press CTRL+SHIFT+1 to have the app type your snippet.

If you want the app to always run in the background, minimize it to the tray.

Implementation notes — how some features work {#implementation-notes-%E2%80%94-how-some-features-work}

Here are a few implementation details for anyone curious or wanting to extend the app.

  • Global hotkey registration

    The app uses the Windows API functions RegisterHotKey and UnregisterHotKey via P/Invoke. The main form registers a hotkey during construction and handles the hotkey event in WndProc by checking for WM_HOTKEY and the registered id.

    Example P/Invoke signatures used in Form1.cs:

    [DllImport("user32.dll")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
    
    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
    
    private const int WM_HOTKEY = 0x0312;
    private const int HOTKEY_ID = 1;
    
  • Typing the text

    When the hotkey fires the app calls an async TypePredefinedText() method. It uses SendKeys.SendWait() to send characters one-by-one to the foreground window and Task.Delay() with a randomized interval to simulate human typing. A short initial delay ensures the hotkey release doesn't interfere with the first character.

    A simplified version of TypePredefinedText() looks like:

    private async void TypePredefinedText()
    {
        SendKeys.Flush();
        await Task.Delay(250); // ensure hotkey is released
    
        int baseDelay = 310 - (typingSpeed * 30);
        int variation = Math.Max(10, baseDelay / 3);
        Random random = new Random();
    
        foreach (char c in predefinedText)
        {
            SendKeys.SendWait(c.ToString());
            SendKeys.Flush();
            await Task.Delay(Math.Max(20, random.Next(Math.Max(10, baseDelay - variation), baseDelay + variation)));
        }
    }
    
  • Timing and realism

    Typing speed is an integer from 1 (slowest) to 10 (fastest). The app converts that value into a base delay and adds a bit of random variation per character. This creates a natural rhythm instead of a machine-gun paste.

  • Settings persistence

    User configuration (the predefined text and the typing speed) are serialized to settings.json in the application directory using System.Text.Json. The app loads settings on startup and writes them whenever the user updates the snippet or changes speed.

    The simple settings DTO used for JSON (and its defaults):

    public class AppSettings
    {
        public string PredefinedText { get; set; } = string.Empty;
        public int TypingSpeed { get; set; } = 5;
    }
    
  • System tray

    A NotifyIcon with a ContextMenuStrip lets the app hide in the tray and provide quick actions (Show / Exit). The form's Dispose method unregisters the hotkey and disposes of the tray icon to keep the system state clean.

Extending Hotkey Typer — ideas {#extending-hotkey-typer-%E2%80%94-ideas}

  • Support multiple named snippets and a configurable hotkey per snippet
  • Add a CLI mode for scripting or remote triggering
  • Use the Windows Input Injection APIs for applications that block SendKeys
  • Add an option to send the entire string as a clipboard paste (with clipboard restoration) for faster input when acceptable

Notes and security

Because Hotkey Typer sends keystrokes to other applications, some security software may flag it as automation. This is expected for tools that simulate input — distribute and run it only in environments you control.

Also, typing into elevated apps may require Hotkey Typer to run with the same elevation level.

Isn't this in ZoomIt?

Why yes it is! I couldn't remember if this was added into some tool that I use, so I vibed coded it in 10 minutes :)

Fun fact, it is in SysInternals/ZoomIt which is also available in PowerToys and works pretty similar.


Thanks for reading — hope Hotkey Typer makes your demos smoother!

]]>
Introducing Bingo-o-matic: Your Ultimate Bingo Management App https://staging.montemagno.com/introducing-bingo-o-matic-your-ultimate-bingo-management-app/ 6834c49620e2c90001f0aa79 Mon, 26 May 2025 19:58:22 GMT

Are you tired of managing bingo games with paper cards and manual tracking? Look no further! I'm thrilled to announce the release of Bingo-o-matic, a comprehensive bingo management application designed to make hosting and playing bingo games easier and more enjoyable than ever before.

What is Bingo-o-matic?

Bingo-o-matic is a modern, user-friendly application that digitizes the entire bingo experience. Whether you're hosting a family game night, running a community fundraiser, or organizing a classroom activity, Bingo-o-matic provides all the tools you need to create, manage, and play bingo games with minimal effort.

Play traditional number-based bingo or unleash your creativity with fully customizable bingo sets! From holiday themes to educational concepts, company events to baby showers - the possibilities are endless. Create your own unique bingo experience tailored to any occasion or audience.

Key Features

  • Standard and Custom Bingo: Play classic numbered bingo or create themed sets with your own content
  • Generate Random Bingo Cards: Instantly create unique bingo cards for all your players
  • Print Custom Cards: Easily print physical cards for your custom bingo sets
  • Real-time Calling Tool: Call out bingo items with an intuitive interface
  • History Tracking: Keep track of called items to verify winning cards
  • Multiple Theme Options: Choose from light and dark themes for comfortable viewing
  • Offline Support: Play anytime, anywhere, even without an internet connection
  • Mobile-Friendly Design: Enjoy a seamless experience on any device

Screenshots

Standard Bingo mode with traditional numbered board Classic B-I-N-G-O with standard numbered calling interface

Custom Bingo interface with themed content Play with customized content perfect for themed events and educational settings

Custom bingo set creation interface Easy-to-use editor for creating and saving your own custom bingo sets

Getting Started

Getting started with Bingo-o-matic is incredibly simple:

  1. Visit https://www.bingo-o-matic.com
  2. Create a new bingo set from scratch or browse through our collection of pre-made templates to save time
  3. Generate as many unique cards as you need for your players - each card is randomized for fair play
  4. Use the intuitive calling interface to manage your game and track progress in real-time

Install as a Progressive Web App

One of the most exciting features of Bingo-o-matic is its Progressive Web App (PWA) capabilities. This modern web technology allows the application to function like a native mobile or desktop app while still being accessible through any web browser.

What does this mean for you?

Installing Bingo-o-matic as a PWA gives you several advantages:

  • Faster loading times - The app caches resources locally for instant access
  • Offline functionality - Continue playing even when your internet connection is spotty
  • App-like experience - Opens in its own window without browser navigation bars
  • Easy access - Pin it to your taskbar, dock, or home screen for quick launching

How to install:

  1. Navigate to https://www.bingo-o-matic.com using any modern web browser
  2. On desktop computers: Look for the install icon (usually a download or plus symbol) in your browser's address bar, or check the browser menu for "Install Bingo-o-matic"
  3. On mobile devices: Tap the share button and select "Add to Home Screen" from the menu options
  4. Once installed, Bingo-o-matic will appear in your applications and can be launched just like any other app

The PWA functionality ensures that Bingo-o-matic works reliably in any environment - from remote locations with poor connectivity to busy venues with crowded networks. Your bingo games can continue uninterrupted! Learn more about Progressive Web Apps on web.dev.


Behind the Scenes: The Technical Side of Bingo-o-matic

Technology Stack and Architecture

Bingo-o-matic leverages cutting-edge web technologies to deliver a seamless, high-performance experience. At its core, the application is built using Blazor WebAssembly, Microsoft's web UI framework that allows developers to build interactive web applications using C# instead of JavaScript.

Why Blazor WebAssembly?

  • Performance: Runs at near-native speed in the browser through WebAssembly
  • Type Safety: C#'s strong typing system reduces runtime errors
  • Ecosystem: Access to the entire .NET ecosystem and NuGet packages
  • Developer Experience: Rich tooling and debugging capabilities

Technical Components:

Development Workflow and Tools

The entire development process was revolutionized by leveraging AI-powered development tools:

Visual Studio Code served as the primary development environment, providing excellent Blazor debugging capabilities and integrated terminal access for .NET CLI commands.

GitHub Copilot Agent Mode wrote pretty much all of the code by providing intelligent code completions and suggestions that understood the context of Blazor components, helping accelerate development while maintaining code quality standards. It created the base app features, added new features, implemented advanced logic and styles, and so much more... including this blog post!

GitHub Copilot Coding Agent assisted with architectural decisions, best practice implementations, and complex problem-solving scenarios specific to Progressive Web App development all directly from GitHub.com.

This AI-assisted development approach reduced development time significantly while ensuring adherence to modern web development patterns and Blazor-specific best practices.

Cloud Infrastructure and Deployment

Azure Static Web Apps provides the hosting infrastructure with several key benefits:

  • Automated CI/CD Pipeline: GitHub Actions automatically build and deploy the application whenever code is pushed to the main branch
  • Global Content Delivery: The app is distributed across Microsoft's global CDN network, ensuring fast load times worldwide
  • Automatic HTTPS: Built-in SSL certificates provide secure connections without additional configuration
  • Custom Domain Support: Easy integration with custom domains and DNS management

The deployment process is fully automated - from code commit to live production deployment typically takes less than 3 minutes.

Progressive Web App Implementation

The PWA features are implemented through:

  • Service Worker: Handles caching strategies and offline functionality
  • Web App Manifest: Defines how the app appears when installed on devices
  • Cache Strategies: Intelligent caching of static assets and API responses
  • Background Sync: Ensures data consistency when connectivity is restored

I welcome contributions and feedback from the community to make Bingo-o-matic even better!

]]>
Visual Studio Code, your new Markdown editor https://staging.montemagno.com/visual-studio-code-your-new-markdown-editor/ 598df8f2c121b60019bf2fec Wed, 13 Jul 2016 17:44:10 GMT I feel like I have been spoiled for a long time using macOS as there have been a plethora of great Markdown editors. Now that I am full time on a Surface Book and Windows 10 it saddened me that a version of Mou wasn’t coming or planned at all. I write Markdown just about every day between the libraries on my GitHub and writing blogs and documentation. I have always used VS Code for just light weight text editing and now that it not only runs everywhere, but also supports all sorts of extensions I thought there had to be some form of markdown extension to get me through the day.

 When you boot up VS Code, it isn’t straight forward as to how to get to extensions.You will need to go to View -> Extensions

This brings up the Extensions manager and if you type in @popular then you will see the top extensions. (#1 being C#, which is awesome).

Simply searching for “markdown” gets you into a world of trouble as there are tons of hits all with no icons or real reviews or downloads. Do not worry because I have done all the hard work for you and test a bunch of them out and the one we want to install is “Auto-Open Markdown Preview” (currently version 0.0.3), because it is AMAZING.

Now, you will probably have to re-start and then just open up a markdown file:

Glorious! With images and everything. It is awesome! Enjoy!

]]>