<?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>DEV Community: Cesar Castillo</title>
    <description>The latest articles on DEV Community by Cesar Castillo (@cgcm070).</description>
    <link>https://dev.to/cgcm070</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%2F3744302%2Ff863388d-f534-425d-88ec-0f5533a96933.jpeg</url>
      <title>DEV Community: Cesar Castillo</title>
      <link>https://dev.to/cgcm070</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cgcm070"/>
    <language>en</language>
    <item>
      <title>Just Launched My Portfolio — What Do You Think?</title>
      <dc:creator>Cesar Castillo</dc:creator>
      <pubDate>Sat, 21 Feb 2026 18:10:08 +0000</pubDate>
      <link>https://dev.to/cgcm070/just-launched-my-portfolio-what-do-you-think-336j</link>
      <guid>https://dev.to/cgcm070/just-launched-my-portfolio-what-do-you-think-336j</guid>
      <description>&lt;h3&gt;
  
  
  After procrastinating for way too long, I finally built and shipped my portfolio:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://cgcm-portfolio.vercel.app" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;What I'm looking for&lt;br&gt;
This is my first real portfolio, so I'd love your honest feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Design&lt;/strong&gt; — Does it look professional? Easy on the eyes?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Navigation&lt;/strong&gt; — Can you find what you're looking for quickly?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content&lt;/strong&gt; — Are the project descriptions clear?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile experience&lt;/strong&gt; — How does it feel on your phone?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stack&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular 19&lt;/li&gt;
&lt;li&gt;Tailwind CSS v4&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;What would you change? What works well?&lt;/strong&gt;&lt;br&gt;
Drop your thoughts below — all constructive criticism is welcome! 🙏&lt;br&gt;
&lt;em&gt;Thanks for taking the time to check it out!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>webdev</category>
      <category>design</category>
      <category>learning</category>
    </item>
    <item>
      <title>Track Your GitHub Copilot Pro from the Terminal 🖥️ - New UI 🧑‍🎨</title>
      <dc:creator>Cesar Castillo</dc:creator>
      <pubDate>Sat, 14 Feb 2026 00:49:28 +0000</pubDate>
      <link>https://dev.to/cgcm070/track-your-github-copilot-pro-from-the-terminal-91n</link>
      <guid>https://dev.to/cgcm070/track-your-github-copilot-pro-from-the-terminal-91n</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;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Cesar Castillo&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/CGCM070/copilot-usage_tui" rel="noopener noreferrer"&gt;https://github.com/CGCM070/copilot-usage_tui&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  From Invisible to Visible
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stop guessing. Start knowing.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;GitHub Copilot Pro gives you 300 requests per month… but having to go to the site, navigate through menus, and dig into a specific section just to check your usage? That’s tedious&lt;/p&gt;

&lt;p&gt;I built a terminal-based TUI that transforms your Copilot usage from an invisible mystery into a beautiful, real-time dashboard. Because developers deserve to know exactly how they're using their AI pair programmer.&lt;/p&gt;


&lt;h2&gt;
  
  
  What I Built : Copilot-usage
&lt;/h2&gt;

&lt;p&gt;A Rust-based CLI  tool with an interactive terminal UI that tracks GitHub Copilot Pro usage in real-time, featuring progress bars, per-model statistics, and seamless &lt;strong&gt;Waybar&lt;/strong&gt; integration for &lt;strong&gt;Hyprland&lt;/strong&gt; users.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;If you're a GitHub Copilot Pro user, you know the drill:&lt;br&gt;
You get 300 premium requests per month&lt;br&gt;
There is a page where you can check usage…&lt;br&gt;
But you have to go to the site, open the right section, and dig through settings to find it&lt;br&gt;
So you’re never quite sure where you stand until you manually go look&lt;br&gt;
300 requests. Visibility — technically. Convenience? Not so much.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Solution: Copilot Usage
&lt;/h3&gt;

&lt;p&gt;I built a terminal dashboard that gives you complete visibility into your Copilot consumption with zero friction.&lt;/p&gt;


&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;📊 Beautiful Terminal Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time progress bars with color-coded zones (green → orange → red)&lt;/li&gt;
&lt;li&gt;Per-model usage breakdown (GPT-4, Claude 3.5, Gemini, etc.)&lt;/li&gt;
&lt;li&gt;Compact, density-focused layout inspired by &lt;code&gt;btop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;9 gorgeous color themes: Dark, Nord, Monokai, Gruvbox, Catppuccin, OneDark, TokyoNight, Solarized, Kanagawa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;⚡ Async Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Non-blocking UI with tokio async runtime&lt;/li&gt;
&lt;li&gt;Smooth spinner animations during API calls (20 FPS)&lt;/li&gt;
&lt;li&gt;Cancelable operations with Escape key&lt;/li&gt;
&lt;li&gt;Background refresh while you keep working&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🎨 Theme System&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant theme switching without exiting TUI&lt;/li&gt;
&lt;li&gt;Persistent theme configuration&lt;/li&gt;
&lt;li&gt;Consistent warning (orange) and error (red) colors across all themes&lt;/li&gt;
&lt;li&gt;Segmented progress bars for visual feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;💾 Smart Caching&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local cache with 5-minute TTL (configurable)&lt;/li&gt;
&lt;li&gt;Cache status indicator (Fresh/Expired/Missing)&lt;/li&gt;
&lt;li&gt;Manual refresh with 'r' key&lt;/li&gt;
&lt;li&gt;Automatic cache invalidation on &lt;code&gt;--refresh&lt;/code&gt; flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔧 Interactive Modals&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Command menu (press &lt;code&gt;/&lt;/code&gt;) for quick actions&lt;/li&gt;
&lt;li&gt;Theme selector with live preview&lt;/li&gt;
&lt;li&gt;Help dialog with all keybindings (press &lt;code&gt;?&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Error dialogs with debug mode toggle (press &lt;code&gt;d&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Cache info modal showing last update time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📈 Waybar Integration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON output for Waybar status bar&lt;/li&gt;
&lt;li&gt;Customizable format strings&lt;/li&gt;
&lt;li&gt;Shows percentage in your status bar&lt;/li&gt;
&lt;li&gt;Perfect for Hyprland/wayland users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🚀 Zero-Config Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive first-run wizard&lt;/li&gt;
&lt;li&gt;Automatic GitHub username detection&lt;/li&gt;
&lt;li&gt;Fine-grained PAT or classic token support&lt;/li&gt;
&lt;li&gt;XDG-compliant config directory&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Architecture Deep Dive
&lt;/h2&gt;

&lt;p&gt;This isn't just a simple API wrapper. It's a full async TUI application with clean separation of concerns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│  Terminal UI (ratatui)                                  │
│  ┌──────────────────────────────────────────────────┐   │
│  │  UI Components                                   │   │
│  │  • Header (user info)                            │   │
│  │  • Usage Progress Bar                            │   │
│  │  • Model Usage Table                             │   │
│  │  • Modal Dialogs                                 │   │
│  └──────────────────────────────────────────────────┘   │
│                       ↓                                 │
│  ┌──────────────────────────────────────────────────┐   │
│  │  Event Loop (50ms poll)                          │   │
│  │  • Keyboard input handling                       │   │
│  │  • Async result processing                       │   │
│  │  • Spinner animation updates                     │   │
│  └──────────────────────────────────────────────────┘   │
│                       ↓                                 │
│  ┌──────────────────────────────────────────────────┐   │
│  │  Async Handler (tokio)                           │   │
│  │  • Background API calls                          │   │
│  │  • Cache operations                              │   │
│  │  • mpsc channels for results                     │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────┐
│  GitHub API                                             │
│  • /users/{username}/settings/billing/...              │
│  • 5000 req/hour rate limit                            │
│  • Fine-grained PAT with Plan (Read)                   │
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Async Event Loop Pattern
&lt;/h3&gt;

&lt;p&gt;The heart of the application is a non-blocking event loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Handle user input (non-blocking)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nn"&gt;event&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;poll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Process keyboard events&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Animate spinner during loading&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nd"&gt;matches!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="py"&gt;.state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LoadingRefresh&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;LoadingCache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="nf"&gt;.advance_spinner&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. Check for async results&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;async_handler&lt;/span&gt;&lt;span class="nf"&gt;.try_recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;RefreshComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;update_dashboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;RefreshComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;show_error_modal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;CacheInfoReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;show_cache_modal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&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="c1"&gt;// 4. Render UI (20 FPS)&lt;/span&gt;
    &lt;span class="n"&gt;terminal&lt;/span&gt;&lt;span class="nf"&gt;.draw&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nf"&gt;render_ui&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why async matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls don't freeze the UI&lt;/li&gt;
&lt;li&gt;Spinner animations stay smooth&lt;/li&gt;
&lt;li&gt;Users can cancel operations anytime&lt;/li&gt;
&lt;li&gt;Background tasks complete even after cancel&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Technical Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Modular Component Architecture
&lt;/h3&gt;

&lt;p&gt;Each UI component is a pure function with zero side effects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Pure rendering function - no state mutations&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;render_usage_overall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;UsageStats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ThemeColors&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Calculate progress bar segments&lt;/span&gt;
    &lt;span class="c1"&gt;// Render with theme colors&lt;/span&gt;
    &lt;span class="c1"&gt;// No state changes, no events handled&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to test (input → output)&lt;/li&gt;
&lt;li&gt;No hidden state mutations&lt;/li&gt;
&lt;li&gt;Components compose naturally&lt;/li&gt;
&lt;li&gt;Theme changes apply instantly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. State Machine Pattern
&lt;/h3&gt;

&lt;p&gt;AppState enum models all UI states explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;AppState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;// Main view&lt;/span&gt;
    &lt;span class="n"&gt;LoadingRefresh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// Spinner during API call&lt;/span&gt;
    &lt;span class="nf"&gt;ShowCacheInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CacheInfo&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;    &lt;span class="c1"&gt;// Cache status modal&lt;/span&gt;
    &lt;span class="n"&gt;ShowError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                  &lt;span class="c1"&gt;// Error with debug toggle&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;debug_message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;show_debug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// ... more states&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No boolean flags. No hidden state. Every state is explicit and handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Constant Warning/Error Colors
&lt;/h3&gt;

&lt;p&gt;Across all 9 themes, warning and error colors remain constant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Warning:&lt;/strong&gt; &lt;code&gt;rgb(255, 184, 108)&lt;/code&gt; (orange)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error:&lt;/strong&gt; &lt;code&gt;rgb(255, 85, 85)&lt;/code&gt; (red)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users instantly recognize status regardless of theme.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Compact Layout Philosophy
&lt;/h3&gt;

&lt;p&gt;Inspired by system monitors like &lt;code&gt;btop&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic height:&lt;/strong&gt; Model table resizes based on data (N + 3 rows)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compact width:&lt;/strong&gt; 50% of terminal for readability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal padding:&lt;/strong&gt; Information density over whitespace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rounded borders:&lt;/strong&gt; Modern, polished feel&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Never Exit TUI Philosophy
&lt;/h3&gt;

&lt;p&gt;All operations happen via modals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reconfigure token? Modal dialog&lt;/li&gt;
&lt;li&gt;Change theme? Theme selector modal&lt;/li&gt;
&lt;li&gt;Refresh data? Loading spinner modal&lt;/li&gt;
&lt;li&gt;Error occurred? Error modal with debug info&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The TUI stays alive. No jarring exits. No lost context.&lt;/p&gt;




&lt;h2&gt;
  
  
  📸 Screenshots
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dashboard - Before
&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%2Fjx8vdk51b4rbta25rjaa.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%2Fjx8vdk51b4rbta25rjaa.png" alt="TUI_Gruvbox"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dashboard - After
&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%2Fstu3wnakbtrv4vsp2o9s.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%2Fstu3wnakbtrv4vsp2o9s.png" alt="New"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/KSyDZyW4M7o"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h3&gt;
  
  
  Theme Selector
&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%2Fzkarfv4xulogf3d1q71c.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%2Fzkarfv4xulogf3d1q71c.png" alt="Theme selector"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Waybar Integration
&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%2Fs8r5n6tp177aijzinliw.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%2Fs8r5n6tp177aijzinliw.png" alt="Waybar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Refresh
&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%2Fqgtrgtpikx1dvbtt7auk.gif" 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%2Fqgtrgtpikx1dvbtt7auk.gif" alt="Refresh"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;This project was built with extensive help from GitHub Copilot CLI, turning natural language into idiomatic Rust code.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I Used Copilot CLI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Async Architecture Design&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Best way to structure async TUI in Rust?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot suggested: tokio + mpsc channels + non-blocking event loop&lt;/span&gt;
&lt;span class="c"&gt;# Result: Smooth 20 FPS UI with background API calls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. State Machine Pattern&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "How to model TUI states without boolean flags?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot proposed: AppState enum with exhaustive match&lt;/span&gt;
&lt;span class="c"&gt;# Result: Clean state transitions, no hidden bugs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Theme System&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Implement 9 color themes with constant warning/error colors"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot generated: ThemeColors struct + theme implementations&lt;/span&gt;
&lt;span class="c"&gt;# Result: 9 gorgeous themes with consistent UX&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Progress Bar Segmentation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Create gradient progress bars (green→orange→red)"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot designed: Segmented bar with zone calculations&lt;/span&gt;
&lt;span class="c"&gt;# Result: Visual feedback at a glance&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Cache System&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Implement file-based cache with TTL in Rust"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot built: Cache with CacheStatus enum (Fresh/Expired/Missing)&lt;/span&gt;
&lt;span class="c"&gt;# Result: Fast cached responses, automatic invalidation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copilot suggested the modular component pattern that made the codebase maintainable and testable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edge Cases: Error handling, terminal cleanup on panic, XDG directory resolution - Copilot handled these gracefully.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Installation ( Only tested on LINUX )
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using install script (Recommended)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/CGCM070/copilot-usage.git
&lt;span class="nb"&gt;cd &lt;/span&gt;copilot-usage/
./install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Manual installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--path&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# First run - interactive setup&lt;/span&gt;
copilot-usage

&lt;span class="c"&gt;# Dashboard (uses cache if available)&lt;/span&gt;
copilot-usage

&lt;span class="c"&gt;# Force refresh from API&lt;/span&gt;
copilot-usage &lt;span class="nt"&gt;--refresh&lt;/span&gt;

&lt;span class="c"&gt;# Waybar JSON output&lt;/span&gt;
copilot-usage &lt;span class="nt"&gt;--waybar&lt;/span&gt;

&lt;span class="c"&gt;# Change theme temporarily&lt;/span&gt;
copilot-usage &lt;span class="nt"&gt;--theme&lt;/span&gt; nord

&lt;span class="c"&gt;# Reconfigure token/theme&lt;/span&gt;
copilot-usage reconfigure

&lt;span class="c"&gt;# Check cache status&lt;/span&gt;
copilot-usage &lt;span class="nt"&gt;--cache-status&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Keybindings (in TUI)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Refresh data from API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open theme selector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show help dialog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open command menu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show cache info&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;q&lt;/code&gt;  &lt;code&gt;Esc&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Quit / Close modal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;File: &lt;code&gt;~/.config/copilot-usage/config.toml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;token&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ghp_..."&lt;/span&gt;
&lt;span class="py"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dark"&lt;/span&gt;
&lt;span class="py"&gt;cache_ttl_minutes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="py"&gt;waybar_format&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{}"&lt;/span&gt;
&lt;span class="py"&gt;username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"octocat"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Required GitHub Permissions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fine-grained PAT&lt;/strong&gt; with &lt;code&gt;Plan (Read)&lt;/code&gt; permission&lt;/li&gt;
&lt;li&gt;Classic tokens need &lt;code&gt;read:user&lt;/code&gt; scope&lt;/li&gt;
&lt;li&gt;NOT "Copilot Requests" - different permission!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Notification Support&lt;/strong&gt; - Alert when usage &amp;gt; 80%&lt;br&gt;
&lt;strong&gt;Historical Graphs&lt;/strong&gt; - Usage trends over time&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🤝 Open Source&lt;/strong&gt;&lt;br&gt;
This project is open source. Want to contribute?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PRs welcome&lt;/li&gt;
&lt;li&gt;Good first issues: new themes, documentation, tests&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Credits &amp;amp; Thanks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; for Copilot Pro - the AI that powers our coding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; for helping build this tool faster than ever &amp;lt;3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DEV.to&lt;/strong&gt; for hosting this challenge&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Developer Desk Setups: What Do YOU Consider Truly Indispensable?</title>
      <dc:creator>Cesar Castillo</dc:creator>
      <pubDate>Mon, 09 Feb 2026 16:55:18 +0000</pubDate>
      <link>https://dev.to/cgcm070/developer-desk-setups-what-do-you-consider-truly-indispensable-36k</link>
      <guid>https://dev.to/cgcm070/developer-desk-setups-what-do-you-consider-truly-indispensable-36k</guid>
      <description>&lt;h2&gt;
  
  
  What’s the One Thing You Can’t Code Without? Essential Developer Desk Items and the Linus Torvalds Reality Check
&lt;/h2&gt;

&lt;p&gt;We all spend hours — sometimes entire days — in front of our desks writing code, debugging, and shipping features. A good setup can make those hours feel smoother, healthier, and more productive. But what actually matters?&lt;/p&gt;

&lt;p&gt;One thing you notice quickly in the dev community: people are passionate about their setups. Some invest in expensive ergonomic gear, others prefer to keep things extremely simple, yet both approaches seem to work amazingly well.&lt;/p&gt;

&lt;p&gt;Here are the items that come up &lt;strong&gt;again and again&lt;/strong&gt; as game-changers in desk setup threads, comments, and photos across Dev.to, Reddit, and Hacker News.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Most Loved (and Most Debated) Desk Items
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ergonomic Chair&lt;/strong&gt;&lt;br&gt;&lt;br&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%2Fimc8rastkj9c238o8nfa.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%2Fimc8rastkj9c238o8nfa.png" alt="Premium ergonomic chair in developer workspace" width="800" height="531"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
The undisputed king. Herman Miller Aeron, Steelcase Gesture, or more affordable options like Sihoo and Secretlab dominate conversations. Reason: long coding sessions without back pain = more focus and fewer sick days.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Big/High-Quality Monitor(s)&lt;/strong&gt;&lt;br&gt;&lt;br&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%2Frh1vvph7bz2cxlswic68.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%2Frh1vvph7bz2cxlswic68.png" alt="Dual monitor developer setup" width="800" height="525"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Dual setups, ultrawides (34"+), or 4K 27-32" panels. More screen real estate means less tab-switching and easier debugging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mechanical Keyboard&lt;/strong&gt;&lt;br&gt;&lt;br&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%2Fqenref4t95cld2hk1b8m.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%2Fqenref4t95cld2hk1b8m.png" alt="Premium mechanical keyboard on desk" width="800" height="523"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Clicky, tactile, custom — Keychron, Ducky, or full custom builds. Devs love the feel and the speed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Good Lighting&lt;/strong&gt;&lt;br&gt;&lt;br&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%2Fzqb477znkxoqnu29tt03.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%2Fzqb477znkxoqnu29tt03.png" alt="BenQ ScreenBar and desk lighting" width="800" height="517"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Often underrated until someone tries it. BenQ ScreenBar, desk lamps with adjustable temperature, or just natural light setups. Reduces eye strain dramatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Standing Desk or Converter + Ergonomic Mouse&lt;/strong&gt;&lt;br&gt;&lt;br&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%2F2lis4awbgz6tqjzlzmwj.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%2F2lis4awbgz6tqjzlzmwj.png" alt="Standing desk converter and vertical mouse" width="800" height="535"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Alternating sitting and standing, plus vertical mice to avoid wrist pain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cable Management &amp;amp; Small Quality-of-Life Touches&lt;/strong&gt;&lt;br&gt;&lt;br&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%2Fzez8johnn6cv5qy0rznu.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%2Fzez8johnn6cv5qy0rznu.png" alt="Clean cable management and plants" width="800" height="522"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Monitor arms, plants, good headphones, or a clean cable tray.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Linus Torvalds Reminder: Simplicity Works Too
&lt;/h2&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%2F5xtusgxp52vg3ey467k2.jpg" 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%2F5xtusgxp52vg3ey467k2.jpg" alt="Linus Torvalds simple desk setup" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While many of us chase the perfect chair or ultrawide, Linus Torvalds — creator of Linux and Git — keeps his setup remarkably simple: solid hardware, multiple monitors for productivity, but no fancy RGB or obsession with gear. Just tools that get out of the way and let him code.&lt;/p&gt;

&lt;p&gt;It’s a good reality check: you don’t need to spend thousands to be effective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now It’s Your Turn
&lt;/h2&gt;

&lt;p&gt;This post is really about &lt;strong&gt;you&lt;/strong&gt;. What’s the one item (or habit) in your desk setup that you genuinely consider indispensable?&lt;/p&gt;

&lt;p&gt;For me, it's my simple wireless mouse and regular weight training 🏋️‍♂️ — keeps my wrist happy and my energy up.&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%2Fplydvpl3s4nu1v19p64c.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%2Fplydvpl3s4nu1v19p64c.png" alt="Mouse" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drop your must-have in the comments. Bonus points if you share a photo or quick description! The best recommendations always come from the community 👇&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;productivity&lt;/strong&gt; &lt;strong&gt;discuss&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>NotebookLM Enhancer - UPDATE ✨</title>
      <dc:creator>Cesar Castillo</dc:creator>
      <pubDate>Wed, 04 Feb 2026 21:06:09 +0000</pubDate>
      <link>https://dev.to/cgcm070/notebooklm-enhancer-2j6p</link>
      <guid>https://dev.to/cgcm070/notebooklm-enhancer-2j6p</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;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; Cesar Castillo&lt;br&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/CGCM070/NotebookLM_Enhancer" rel="noopener noreferrer"&gt;https://github.com/CGCM070/NotebookLM_Enhancer&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  From Chaos to Order
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🎉 UPDATE :&lt;/strong&gt; Just released &lt;strong&gt;Smart Batch Delete&lt;/strong&gt; : delete multiple notes with one click! No more 60+ clicks to clean up 20 notes. Check out the new feature section below! 👇&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a Chrome Extension That Finally Organizes NotebookLM&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A Chrome extension that transforms NotebookLM's chaotic sidebar into a beautifully organized folder system, because 47 research notes shouldn't look like a pile of digital laundry.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Problem That Drove Me Crazy
&lt;/h3&gt;

&lt;p&gt;If you've used &lt;a href="https://notebooklm.google.com" rel="noopener noreferrer"&gt;NotebookLM&lt;/a&gt;, you know it's &lt;em&gt;magical&lt;/em&gt; for research. Upload PDFs, paste URLs, ask questions it's like having a research assistant that never sleeps.&lt;/p&gt;

&lt;p&gt;But there's one maddening catch: &lt;strong&gt;the sidebar becomes a nightmare when you have more than 10 notes.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Imagine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15 research papers on Spring Framework&lt;/li&gt;
&lt;li&gt;8 articles about microservices
&lt;/li&gt;
&lt;li&gt;12 random bookmarks you saved "for later"&lt;/li&gt;
&lt;li&gt;All. In. One. Giant. List.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No folders. No organization. Just... chaos.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Solution: NotebookLM Enhancer
&lt;/h3&gt;

&lt;p&gt;I built a Chrome extension that injects a complete folder management system directly into NotebookLM's sidebar. &lt;/p&gt;
&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;🗂️ Smart Folder Organization&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create folders and subfolders (1 level deep keeping it simple!)&lt;/li&gt;
&lt;li&gt;Drag &amp;amp; drop notes between folders with smooth animations&lt;/li&gt;
&lt;li&gt;"Inbox" view for unassigned notes&lt;/li&gt;
&lt;li&gt;Each notebook project has isolated folders (no cross-contamination!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🧑‍🎨 Polished UI That Matches NotebookLM&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built with Angular + Tailwind CSS&lt;/li&gt;
&lt;li&gt;Dark/light/system theme toggle&lt;/li&gt;
&lt;li&gt;Minimalist design that feels native&lt;/li&gt;
&lt;li&gt;Smooth expand/collapse animations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🌎Internationalization&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full i18n support (English/Spanish currently)&lt;/li&gt;
&lt;li&gt;One-click language switcher&lt;/li&gt;
&lt;li&gt;All UI text translatable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;💭Intelligent Integrations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click any note → opens native NotebookLM&lt;/li&gt;
&lt;li&gt;Click 3-dots menu → native menu appears aligned to the right (matching native position)&lt;/li&gt;
&lt;li&gt;Drag notes from native sidebar → drops into our folders&lt;/li&gt;
&lt;li&gt;Add new notes button that triggers native NotebookLM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🗑️ Batch Delete&lt;/strong&gt;  &lt;em&gt;NEW!&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select multiple notes at once with checkboxes&lt;/li&gt;
&lt;li&gt;"Selection Mode" toggle with icon in header&lt;/li&gt;
&lt;li&gt;Click any row to toggle selection&lt;/li&gt;
&lt;li&gt;ESC key to cancel selection mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic confirmation&lt;/strong&gt; of NotebookLM's native delete modal - no manual interaction needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Robust Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chrome Extension MV3 (latest manifest version)&lt;/li&gt;
&lt;li&gt;Content Scripts + Shadow DOM for style isolation&lt;/li&gt;
&lt;li&gt;Iframe-based Angular app for the UI&lt;/li&gt;
&lt;li&gt;PostMessage bridge for iframe ↔ page communication&lt;/li&gt;
&lt;li&gt;chrome.storage.sync for persistence across devices&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Architecture Deep Dive
&lt;/h3&gt;

&lt;p&gt;This isn't a simple content script that adds a few buttons. It's a full micro-frontend architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│  NotebookLM Page                                        │
│  ┌──────────────────────────────────────────────────┐   │
│  │  Native Sidebar (hidden but functional)          │   │
│  │  • Still handles clicks &amp;amp; menus                  │   │
│  │  • We extract data from it                       │   │
│  └──────────────────────────────────────────────────┘   │
│                       ↓                                 │
│  ┌──────────────────────────────────────────────────┐   │
│  │  Our Injected Host (Shadow DOM)                  │   │
│  │  ┌───────────────────────────────────────────┐   │   │
│  │  │  Iframe (Angular App)                     │   │   │
│  │  │  • Folder tree                            │   │   │
│  │  │  • Drag &amp;amp; drop (Angular CDK)              │   │   │
│  │  │  • Theme toggle                           │   │   │
│  │  │  • Note add. folder add...                │   │   │
│  │  │  • i18n                                   │   │   │
│  │  └───────────────────────────────────────────┘   │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why an iframe inside Shadow DOM?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolation:&lt;/strong&gt; NotebookLM uses Angular Material with global styles our iframe keeps our Tailwind styles pristine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Content scripts can't easily access iframe internals (and vice versa)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Angular app runs independently without polluting the main page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Communication Flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Content script reads native DOM →  extracts notebook data&lt;/li&gt;
&lt;li&gt;PostMessage to iframe →  Angular displays organized folders&lt;/li&gt;
&lt;li&gt;User drags note to folder →  PostMessage back to content script&lt;/li&gt;
&lt;li&gt;Content script updates chrome.storage.sync&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Technical Decisions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Storage V3 with Notebook Isolation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of one global folder structure, each NotebookLM project gets its own isolated state:&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;// StorageStateV3&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;byNotebook&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uuid-abc-123&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="na"&gt;folders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
      &lt;span class="na"&gt;notebookFolderByKey&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uuid-def-456&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="na"&gt;folders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
      &lt;span class="na"&gt;notebookFolderByKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means your "Work" folder structure doesn't leak into your "Personal" research. Clean separation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Handling MV3 Service Worker Sleep&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chrome MV3 Service Workers sleep after 30 seconds of inactivity. This breaks &lt;code&gt;chrome.runtime&lt;/code&gt; calls.&lt;/p&gt;

&lt;p&gt;Instead of fighting it with "keep-alive" hacks, we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect context invalidation gracefully&lt;/li&gt;
&lt;li&gt;Silently retry on the next frame&lt;/li&gt;
&lt;li&gt;Log to our own &lt;code&gt;NLE.log()&lt;/code&gt; instead of spamming console.warn&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Native Drag Bridge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Making the native NotebookLM sidebar items draggable was tricky. We:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hook &lt;code&gt;dragstart&lt;/code&gt; on native items&lt;/li&gt;
&lt;li&gt;Create an invisible overlay above our iframe during drag&lt;/li&gt;
&lt;li&gt;Calculate drop target using &lt;code&gt;elementFromPoint()&lt;/code&gt; with coordinates&lt;/li&gt;
&lt;li&gt;Result: Native notes can be dropped into our folders seamlessly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. One-Click Batch Delete&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deleting notes in NotebookLM means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click 3-dots menu on a note&lt;/li&gt;
&lt;li&gt;Click "Delete" option
&lt;/li&gt;
&lt;li&gt;Confirm in the modal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeat for every single note&lt;/strong&gt; :(&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With 20 notes to clean up? That's 60+ clicks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our Solution: One-Click Batch Delete&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Modal Handling&lt;/strong&gt;: Content script detects NotebookLM's confirmation dialog and clicks "Delete" automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index Adjustment&lt;/strong&gt;: When notes are deleted, indexes shift - we compensate by tracking deletion count&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RxJS State Management&lt;/strong&gt;: &lt;code&gt;BatchSelectionService&lt;/code&gt; with &lt;code&gt;BehaviorSubjects&lt;/code&gt; for reactive UI updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Auto-Focus Input in Modals&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Small UX detail that makes a huge difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create folder → input already focused, ready to type&lt;/li&gt;
&lt;li&gt;Rename folder → text is pre-selected, just type to replace&lt;/li&gt;
&lt;li&gt;No extra clicks needed&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📸 Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; &lt;br&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%2Fj2vso7uvx6b7t318w28x.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%2Fj2vso7uvx6b7t318w28x.png" alt="Original Notebook1" width="800" height="450"&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%2Fyo5b9f8iaux93gi2tveh.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%2Fyo5b9f8iaux93gi2tveh.png" alt="Original Notebook2" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&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%2Fqq47oynqeno46fte6non.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%2Fqq47oynqeno46fte6non.png" alt="After Enhancer1" width="800" height="427"&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%2Fink8toe9kwpcs9qjwogc.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%2Fink8toe9kwpcs9qjwogc.png" alt="After Enhancer2" width="509" height="893"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Export your notes :&lt;/strong&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%2F6bleewr5lts3orpbmtwn.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%2F6bleewr5lts3orpbmtwn.png" alt="Export your notes" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drag &amp;amp; Drop:&lt;/strong&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%2Fk9s4s89woeq8isnuqfvu.gif" 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%2Fk9s4s89woeq8isnuqfvu.gif" alt="Drang and drop" width="588" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🗑️ Batch Delete&lt;/strong&gt;  &lt;em&gt;NEW!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3z9qj2eqaftxdh2j93h.gif" 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%2Fv3z9qj2eqaftxdh2j93h.gif" alt="Batch delete" width="438" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full video&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://www.youtube.com/watch?v=KpqXmjq_oow" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=KpqXmjq_oow&lt;/a&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;This project was built almost entirely through GitHub Copilot CLI interactions turning natural language into production-ready code.&lt;/p&gt;
&lt;h3&gt;
  
  
  How I Used Copilot CLI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Architecture Decisions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked Copilot: "Best way to inject UI into an existing Angular Material page?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot suggested: Shadow DOM + iframe for isolation&lt;/span&gt;
&lt;span class="c"&gt;# Result: Zero style conflicts with NotebookLM's Material Design&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Content Script Structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "How to structure 8 content scripts that share state?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot proposed: Module pattern with window.__NLE__ namespace&lt;/span&gt;
&lt;span class="c"&gt;# Result: Clean separation, no global pollution&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Drag &amp;amp; Drop Implementation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Bridge native HTML5 drag with Angular CDK drop?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot designed: Overlay system with coordinate translation&lt;/span&gt;
&lt;span class="c"&gt;# Result: Seamless drag from native sidebar to our folders&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Debugging Context Invalidation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Chrome MV3 extension context invalidated errors?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot implemented: Graceful detection + silent retry logic&lt;/span&gt;
&lt;span class="c"&gt;# Result: No console spam, smooth recovery&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. i18n System&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Asked: "Lightweight i18n without ngx-translate bloat?"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot built: Custom TranslationService with lazy loading&lt;/span&gt;
&lt;span class="c"&gt;# Result: ~3KB vs ~50KB, full interpolation support&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wins
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Speed:&lt;/strong&gt; What would have taken weeks took days. Complex features like the drag bridge were implemented in hours, not days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture:&lt;/strong&gt; Copilot suggested patterns I wouldn't have considered (like the iframe-in-shadow approach) that solved isolation problems elegantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edge Cases:&lt;/strong&gt; MV3 quirks, Material Design menu positioning, SPA navigation detection Copilot handled these gracefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning:&lt;/strong&gt; Every interaction was a learning moment :) . I now understand Chrome Extension architecture, Angular standalone components, and Tailwind customization.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Chrome Web Store Launch&lt;/strong&gt; - Polish, package, publish&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More Languages&lt;/strong&gt; - French, German, Portuguese (easy with our i18n system)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search &amp;amp; Filter&lt;/strong&gt; - Find notes within folders instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard Shortcuts&lt;/strong&gt; - Power-user features (Ctrl+Shift+N for new folder)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;🤝 Open Source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project will be open-sourced. Want to contribute?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PRs welcome&lt;/li&gt;
&lt;li&gt;Good first issues: translations, themes, documentation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Credits &amp;amp; Thanks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google&lt;/strong&gt; for NotebookLM an incredible research tool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; for turning ideas into code faster than ever &amp;lt;3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; for making dark mode trivial&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DEV.to&lt;/strong&gt; for hosting this challenge and bringing the community together&lt;/li&gt;
&lt;/ul&gt;




&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/CGCM070/NotebookLM_Enhancer" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Built with ❤️,  and a lot of help from GitHub Copilot CLI.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;devchallenge&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;githubchallenge&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;cli&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;githubcopilot&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

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