<?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: Gaurav Kumar Singh</title>
    <description>The latest articles on DEV Community by Gaurav Kumar Singh (@gaurav101).</description>
    <link>https://dev.to/gaurav101</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F893926%2Faba99e1d-37d8-4b1a-ab42-802ed842d0e6.jpeg</url>
      <title>DEV Community: Gaurav Kumar Singh</title>
      <link>https://dev.to/gaurav101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gaurav101"/>
    <language>en</language>
    <item>
      <title>From Junior to Staff: How to Build a Safe Team Culture as an Engineerr</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Sun, 04 Oct 2026 04:51:01 +0000</pubDate>
      <link>https://dev.to/gaurav101/from-junior-to-staff-how-to-build-a-safe-team-culture-as-an-engineerr-1m24</link>
      <guid>https://dev.to/gaurav101/from-junior-to-staff-how-to-build-a-safe-team-culture-as-an-engineerr-1m24</guid>
      <description>&lt;p&gt;When people talk about "psychological safety" on dev teams, it usually sounds like corporate HR talk or something managers are supposed to fix. But after 10+ years in the industry, I can tell you this: managers only write the policies. Individual engineers build the actual culture every day in PR comments, Teams messages, design reviews, and live production incidents.&lt;/p&gt;

&lt;p&gt;Whether you're a junior dev shipping your first PR or a Staff engineer designing core systems, you don't need a manager title to make your team a safe, high-performing place to work. Here is how you can build that culture from the ground up.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Get Comfortable Saying "I Don't Know"
&lt;/h2&gt;

&lt;p&gt;Tech has a massive imposter syndrome problem. Juniors feel like they have to know everything, while seniors feel forced to pretend they never make mistakes. The result? People hide bugs, guess instead of asking, and avoid taking on risky tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Power of Senior Ignorance
&lt;/h3&gt;

&lt;p&gt;When a senior engineer openly says &lt;strong&gt;"I don't know"&lt;/strong&gt; or &lt;strong&gt;"Can someone walk me through this?"&lt;/strong&gt;, the entire vibe in the room changes. It signals to everyone else that it's okay to be human.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In Teams Chat:&lt;/strong&gt; Don't just nod along in public channels. Ask openly: &lt;em&gt;"I'm not familiar with how our auth middleware rotates tokens here : can someone drop a link to the docs or give a quick walkthrough?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In Code Reviews:&lt;/strong&gt; Be honest when something isn't your domain: &lt;em&gt;"I haven't touched this database driver before, so I'm focusing my review on the business logic rather than the connection pool logic."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When You Break Stuff:&lt;/strong&gt; Own your mistakes casually: &lt;em&gt;"Staging build is down because I forgot to run migrations locally. My bad fixing it now."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you normalized learning in public, you make it safe for others to ask questions early before a small confusion turns into a production outage.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Ask Questions That Don't Put People on the Defensive
&lt;/h2&gt;

&lt;p&gt;The way you word PR feedback or design critiques directly impacts whether a teammate collaborates with you or puts up a wall. Aggressive questions trigger defensiveness; curious questions lead to real problem-solving.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reframing Your Comments
&lt;/h3&gt;

&lt;p&gt;Small adjustments to your tone can turn a harsh review into a productive discussion:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;High-Tension Phrasing&lt;/th&gt;
&lt;th&gt;High-Safety / Curious Phrasing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;"Why did you use a loop here instead of Map?"&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;"Help me understand the trade-offs of using a loop vs. a Map here."&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;"This design won't scale."&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;"What happens to this queue if traffic spikes 10x during a big sale?"&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;"Why didn't you follow the style guide?"&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;"Looks like the linter missed this formatting issue—should we tweak the linter config or leave this as an exception?"&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quick Tips for Better Framing:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Focus on the code, not the person:&lt;/strong&gt; Ask &lt;em&gt;"How does this function handle null values?"&lt;/em&gt; instead of &lt;em&gt;"Why didn't you handle nulls here?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assume your peer is competent:&lt;/strong&gt; Start with the assumption that they had a good reason for their approach based on the context they had.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask for feedback on your own ideas:&lt;/strong&gt; End design docs or PR descriptions with open prompts like &lt;em&gt;"Where do you think this design breaks?"&lt;/em&gt; or &lt;em&gt;"What edge cases am I missing?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  3. Have Your Teammates' Backs When Things Go Wrong
&lt;/h2&gt;

&lt;p&gt;Team culture isn't tested when everything is quiet—it's tested during Severity 1 outages or intense architecture reviews. As a peer, you have massive power to de-escalate high-stress moments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario A: The Live Outage
&lt;/h3&gt;

&lt;p&gt;During a Sev-1 incident, pressure is high and people panic—especially if they think their code caused it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kill the blame game instantly:&lt;/strong&gt; If someone says &lt;em&gt;"I think my PR broke prod,"&lt;/em&gt; step in: &lt;em&gt;"Don't worry about root cause right now. We fix the issue first, figure out why later. Let's get a rollback done."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pair up:&lt;/strong&gt; Don't leave one engineer struggling alone on an incident call while everyone watches. Jump in: &lt;em&gt;"I'll dig through the logs while you check the database."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scenario B: Harsh Design Reviews
&lt;/h3&gt;

&lt;p&gt;Design reviews can quickly feel like an interrogation if multiple seniors gang up on one flaw.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Redirect aggressive feedback:&lt;/strong&gt; If someone is grilling a presenter, jump in: &lt;em&gt;"That's a fair point about DB locks. Let me write that down as an item to investigate so we can let them finish the rest of the proposal."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Include quieter voices:&lt;/strong&gt; If someone gets talked over, bring them back: &lt;em&gt;"I think He/She was about to make a point about the API contract"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Summary Checklist
&lt;/h2&gt;

&lt;p&gt;Building a good engineering culture doesn't require a title change. Start with these three daily habits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be open about what you don't know.&lt;/strong&gt; Normalize learning out loud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus on trade-offs and curiosity in PRs.&lt;/strong&gt; Trade "Why did you..." for "Help me understand..."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protect your peers during stress.&lt;/strong&gt; Focus on fixing prod over placing blame, and keep design reviews constructive.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Culture comes down to everyday dev-to-dev interactions. Lead by example from where you sit today, and you'll naturally grow into the kind of leader engineers actually want to work with.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>culture</category>
      <category>learning</category>
      <category>leadership</category>
    </item>
    <item>
      <title>The Rise of Automated API Abuse</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Wed, 16 Sep 2026 13:59:09 +0000</pubDate>
      <link>https://dev.to/gaurav101/the-rise-of-automated-api-abuse-4id1</link>
      <guid>https://dev.to/gaurav101/the-rise-of-automated-api-abuse-4id1</guid>
      <description>&lt;p&gt;APIs help apps talk to each other. Websites, mobile apps, payment systems, login pages, and many online tools use APIs every day.&lt;/p&gt;

&lt;p&gt;But attackers also target APIs. Today, automation and AI make this easier and faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Automated API Abuse?
&lt;/h2&gt;

&lt;p&gt;Automated API abuse happens when bots or scripts misuse an API.&lt;/p&gt;

&lt;p&gt;Instead of a real person using an app slowly, a bot sends many requests very quickly.&lt;/p&gt;

&lt;p&gt;For example, attackers may use bots to try many passwords, create fake accounts, scrape data, test stolen cards, abuse discounts, send spam, or search for weak API endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AI Makes It Worse
&lt;/h2&gt;

&lt;p&gt;AI helps people build software faster. This is useful for developers, but attackers can also use it.&lt;/p&gt;

&lt;p&gt;Attackers can use AI to write attack scripts, understand API documents, find weak endpoints, change attacks quickly, and create many request types.&lt;/p&gt;

&lt;p&gt;This means even less-skilled attackers can build stronger attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bots Move at Machine Speed
&lt;/h2&gt;

&lt;p&gt;Humans are slow. Bots are fast.&lt;/p&gt;

&lt;p&gt;A real user may send a few requests in a minute. A bot can send thousands.&lt;/p&gt;

&lt;p&gt;Bots can also use many IP addresses, accounts, and devices. This makes the attack harder to spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rate Limiting Is Not Enough
&lt;/h2&gt;

&lt;p&gt;Rate limiting controls how many requests a user or IP address can send.&lt;/p&gt;

&lt;p&gt;For example, an API may allow only 100 requests per minute.&lt;/p&gt;

&lt;p&gt;This helps, but attackers can avoid simple limits by using many IP addresses, many accounts, different headers, and different locations. They can also slow down the attack just enough to stay below the limit.&lt;/p&gt;

&lt;p&gt;Simple rate limits often miss modern API abuse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Static WAFs Struggle
&lt;/h2&gt;

&lt;p&gt;A Web Application Firewall, or WAF, blocks known bad traffic.&lt;/p&gt;

&lt;p&gt;Older WAFs often use fixed rules. They look for known attack patterns.&lt;/p&gt;

&lt;p&gt;But API abuse can look normal. The request may use the correct URL, format, and login token.&lt;/p&gt;

&lt;p&gt;The problem is not always the request itself. The problem is the behavior.&lt;/p&gt;

&lt;p&gt;A static WAF may miss abuse when requests look valid, attackers change their patterns, real accounts are used, traffic comes from many places, or the abuse happens slowly over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why APIs Are Easy Targets
&lt;/h2&gt;

&lt;p&gt;Many apps have lots of APIs. Some are public, some are private, and some are forgotten.&lt;/p&gt;

&lt;p&gt;APIs become risky when they have weak authentication, share too much data, trust user input too much, are not monitored, or are not updated.&lt;/p&gt;

&lt;p&gt;Attackers use automation to test these weak points quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Business Impact
&lt;/h2&gt;

&lt;p&gt;Automated API abuse can cause serious damage.&lt;/p&gt;

&lt;p&gt;It can lead to account takeover, data leaks, fraud, higher server costs, slow services, poor customer experience, and loss of trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better Protection
&lt;/h2&gt;

&lt;p&gt;Companies need more than basic rate limits and static WAF rules.&lt;/p&gt;

&lt;p&gt;Better protection includes bot detection, behavior monitoring, strong login security, API discovery, anomaly detection, adaptive rate limits, and good logging and alerts.&lt;/p&gt;

&lt;p&gt;Security teams should ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this behavior look normal for a real user?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Automated API abuse is growing because APIs are everywhere and AI makes automation easier.&lt;/p&gt;

&lt;p&gt;Traditional rate limiting and static WAFs still help, but they are not enough alone.&lt;/p&gt;

&lt;p&gt;Modern API security must watch behavior, detect bots, and react quickly before abuse causes damage.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Great AI Mirage: Are We Buying Innovation or Just Badges?</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Sat, 22 Aug 2026 04:56:01 +0000</pubDate>
      <link>https://dev.to/gaurav101/the-great-ai-mirage-are-we-buying-innovation-or-just-badges-1cnn</link>
      <guid>https://dev.to/gaurav101/the-great-ai-mirage-are-we-buying-innovation-or-just-badges-1cnn</guid>
      <description>&lt;p&gt;Everywhere you look, the narrative is the same: innovation begins and ends with AI/ML. Companies are desperate. They are pouring millions of dollars into integrations—often just to plug in a basic AI chatbot—simply to stamp an "AI-Powered" badge on their landing pages. &lt;/p&gt;

&lt;p&gt;But if we strip away the marketing hype and look at the actual reality, a troubling question emerges: &lt;strong&gt;Where is the world-changing technology built &lt;em&gt;by&lt;/em&gt; AI?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Outside of tech demos, the everyday consumer experience hasn't fundamentally shifted. Instead, the AI landscape currently looks like a modern gold rush, but with a twist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Only People Making Money Are Selling Shovels:&lt;/strong&gt; Except for a select few selling hardware, infrastructure, or generative AI tokens, most companies are bleeding cash on AI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "Badge" Economy:&lt;/strong&gt; Massive capital is being spent on optics and FOMO (Fear Of Missing Out) rather than tangible, revolutionary utility. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Missing Breakthroughs:&lt;/strong&gt; We see incremental software updates, but we haven't seen a completely new, world-changing technology emerge that solves fundamental human problems better than traditional tech.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Are we investing in the next internet, or are we just funding the most expensive marketing campaign in tech history? &lt;/p&gt;

&lt;p&gt;It's time to shift the conversation from &lt;em&gt;how much&lt;/em&gt; we are spending on AI to &lt;em&gt;what value&lt;/em&gt; it is actually delivering to the end-user. &lt;/p&gt;




&lt;p&gt;🗣️ &lt;strong&gt;To my network of founders, developers, and tech leaders:&lt;/strong&gt; &lt;br&gt;
Are you seeing genuine, foundational innovation from AI in your sectors, or is the pressure to get the "AI badge" overshadowing real product value? Let's discuss in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>An Evening in the Monsoon Season - Rain, Tea, and Samosas</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Sat, 01 Aug 2026 04:42:52 +0000</pubDate>
      <link>https://dev.to/gaurav101/an-evening-in-the-monsoon-season-rain-tea-and-samosas-2p1d</link>
      <guid>https://dev.to/gaurav101/an-evening-in-the-monsoon-season-rain-tea-and-samosas-2p1d</guid>
      <description>&lt;p&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend-2026-07-29"&gt;Frontend Challenge - Comfort Food Edition, CSS Art&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;Nothing says comfort like a piping hot cup of cutting chai on a rainy monsoon afternoon in India. Listening to the pitter-patter of raindrops against the window while soft, slow music plays in the background, paired with a plate of crisp pakodas, sizzling samosas and a hot cup of tea (adrak wali chai (Ginger Tea )  —it’s pure bliss.&lt;/p&gt;

&lt;p&gt;I wanted to capture that nostalgic, warm atmospheric vibe entirely using HTML and CSS. From the rich gradient of brewed tea and gentle ripples in the cup to the soft wisps of steam rising against the rainy backdrop, this is a tribute to India's favorite monsoon ritual!&lt;/p&gt;

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

&lt;p&gt;Codepen: &lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://codepen.io/editor/Gaurav-Kumar-Singh-the-styleful/pen/019fbb78-e1c9-7e95-a29e-da83d6af65c7" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;codepen.io&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/nmt4jn"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;Building this piece was all about mastering fine visual details and CSS animations:&lt;/p&gt;

&lt;p&gt;Layering &amp;amp; Shapes: Creating the teacup, saucer, and interior liquid surface using carefully placed border-radius, box-shadow, and radial-gradient properties to achieve realistic depth and lighting.&lt;/p&gt;

&lt;p&gt;Steam Wisps: I created subtle steam animation keyframes (@keyframes steamRise) using soft radial gradients and CSS filter: blur() to give the steam a naturally diffused look as it dissipates into the air.&lt;/p&gt;

&lt;p&gt;Surface Ripples: Adding delicate, looping CSS animations to simulate gentle ripples on the tea's surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned &amp;amp; What's Next
&lt;/h2&gt;

&lt;p&gt;&lt;del&gt;Fine-tuning the animation timing and keyframe delays was key to making the steam and ripples feel natural rather than mechanical. Next, I’d love to add interactive elements—like hover effects that react to cursor movement or toggleable light/dark themes!&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;Building this project evolved from a pure CSS art experiment into a full-fledged &lt;strong&gt;React application&lt;/strong&gt;! Here are a few key insights from the process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fine-Tuning Animations:&lt;/strong&gt; Adjusting animation timing and keyframe delays was critical for making the rising steam and subtle surface ripples feel natural rather than mechanical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio Integration &amp;amp; State Management:&lt;/strong&gt; Implementing ambient sound effects (like soothing rain and background tunes) required managing React state effectively to ensure smooth audio playback and control toggles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Customization:&lt;/strong&gt; Adding a dedicated settings panel gave users control over sound, themes, and interactive elements to create their ideal cozy environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔗 Live Links &amp;amp; Project Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🚀 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://chai-samosa-monsoon.vercel.app/" rel="noopener noreferrer"&gt;Chai &amp;amp; Samosa Monsoon Experience&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📂 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/gaurav101/chai-samosa-monsoon" rel="noopener noreferrer"&gt;gaurav101/chai-samosa-monsoon&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>css</category>
      <category>monsoon</category>
    </item>
    <item>
      <title>The Secret Debugging Tool You're Not Using</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Sun, 26 Jul 2026 06:22:32 +0000</pubDate>
      <link>https://dev.to/gaurav101/the-secret-debugging-tool-youre-not-using-1gb3</link>
      <guid>https://dev.to/gaurav101/the-secret-debugging-tool-youre-not-using-1gb3</guid>
      <description>&lt;p&gt;We’ve all been there: It’s 11 PM, the bug is still alive, your tests are failing, and you’re about to throw your laptop out the window. &lt;/p&gt;

&lt;p&gt;We usually view debugging as a pure logic problem: stack traces, breakpoints, and logs. But &lt;strong&gt;Emotional Intelligence (EQ)&lt;/strong&gt; is often the real reason you fix a bug in 20 minutes instead of 3 hours. &lt;/p&gt;

&lt;p&gt;Here is how EQ actually applies to your daily workflow:&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Spotting Tunnel Vision Before It Wastes Your Time
&lt;/h2&gt;

&lt;p&gt;Frustration causes confirmation bias. You start forcing your initial hypothesis (&lt;em&gt;"It MUST be the cache!"&lt;/em&gt;) even when the logs say otherwise.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EQ Move:&lt;/strong&gt; Recognize physical signs like tight shoulders or rage-typing. Take a 5-minute bio-break. Stepping away resets your mental stack, which is usually faster than another hour of blind grinding.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Separating &lt;code&gt;code.hasBug()&lt;/code&gt; from &lt;code&gt;dev.isBad()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A stubborn bug easily triggers imposter syndrome: &lt;em&gt;"A senior dev would have solved this already."&lt;/em&gt; That inner voice just adds noise to your debugging stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EQ Move:&lt;/strong&gt; Reframe the problem objectively:

&lt;ul&gt;
&lt;li&gt;❌ &lt;em&gt;"I don't know what I'm doing."&lt;/em&gt; (Emotion)&lt;/li&gt;
&lt;li&gt;✅ &lt;em&gt;"This async function isn't returning the expected payload."&lt;/em&gt; (Fact)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debug the code, not your self-worth.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Handling Spicy Bug Reports
&lt;/h2&gt;

&lt;p&gt;A ticket comes in: &lt;em&gt;"This is completely broken, who let this ship?!"&lt;/em&gt; Your gut reaction might be to get defensive or send a passive-aggressive response.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EQ Move:&lt;/strong&gt; Filter out the noise. Translate panic or bad phrasing into actionable facts. Reply calmly to de-escalate, pull the missing repro steps, and ship the fix without unnecessary Slack drama.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Rubber Ducking and Asking for Help (Ego-Free)
&lt;/h2&gt;

&lt;p&gt;How many times have you fixed a bug &lt;em&gt;just&lt;/em&gt; by explaining it out loud to a peer? Sitting in silent frustration for hours doesn't make you a hero; it just delays the feature.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EQ Move:&lt;/strong&gt; Treat asking for help as an optimization tactic. Send a concise message with context:
&amp;gt; &lt;em&gt;"Hey, expecting X, getting Y. Already tried A and B. Got 5 mins to glance at this snippet?"&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Staying Cool During Prod Outages
&lt;/h2&gt;

&lt;p&gt;Panicked devs make bad hotfixes and type typos straight into production consoles. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EQ Move:&lt;/strong&gt; The calmest dev in the room becomes the effective incident commander. Slow down, verify facts before firing off commands, and keep communication clear. Clear heads drop downtime.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Debugging isn't just &lt;strong&gt;Dev vs. Code&lt;/strong&gt;—it’s &lt;strong&gt;Dev vs. Emotional Reactivity&lt;/strong&gt;. The fastest problem solvers aren't always the ones who memorized the entire language spec. They’re the ones who catch their frustration early, communicate clearly under pressure, and keep their head clear.&lt;/p&gt;

&lt;p&gt;Next time you get stuck, ask yourself: &lt;strong&gt;"Am I debugging the system, or am I debugging my mood?"&lt;/strong&gt; Fix the mood first, and the logic gets a lot easier to trace.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>The Most Critical Architecture in Tech: Psychological Safety</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Fri, 17 Jul 2026 12:19:11 +0000</pubDate>
      <link>https://dev.to/gaurav101/the-most-critical-architecture-in-tech-psychological-safety-2el9</link>
      <guid>https://dev.to/gaurav101/the-most-critical-architecture-in-tech-psychological-safety-2el9</guid>
      <description>&lt;p&gt;Every engineer knows that sudden, cold dread when a production build breaks. But what happens &lt;em&gt;after&lt;/em&gt; the break tells you everything about your engineering culture. If the first instinct is to find someone to blame, your team has a critical bug in its foundation — and no amount of CI/CD tooling will patch it.&lt;/p&gt;

&lt;p&gt;Psychological safety isn't an HR buzzword. It's a technical property of the system, as real as uptime or test coverage. It's the human &lt;code&gt;try/catch&lt;/code&gt; block that keeps a team resilient under failure. Strip it out, and innovation stalls, code quality degrades, and tech debt quietly compounds until the whole thing collapses under its own weight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Psychological Safety Is a Codebase Concern
&lt;/h2&gt;

&lt;p&gt;When engineers are afraid of looking incompetent, they don't just feel bad — they ship worse software. That fear propagates directly into the codebase in a few predictable ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Silent outages, slow recovery.&lt;/strong&gt; When people fear reprimand, they hide mistakes, delay escalating bugs, or slap a quick patch over the symptom instead of digging into the root cause. Teams with high safety run &lt;strong&gt;blameless postmortems&lt;/strong&gt; that ask &lt;em&gt;how&lt;/em&gt; the system failed, never &lt;em&gt;who&lt;/em&gt; failed it — and they recover faster because of it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech debt that never gets paid down.&lt;/strong&gt; When failure isn't safe, people stop taking risks. Nobody volunteers to refactor the legacy monolith if a resulting bug could show up in their performance review. Teams default to "fragile but predictable" over "robust but risky," and the debt just piles up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull requests as combat instead of collaboration.&lt;/strong&gt; In low-safety environments, code review stops being a shared search for edge cases and turns into something to survive.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The data behind it:&lt;/strong&gt; When Google ran &lt;a href="https://rework.withgoogle.com/en/subjects/team-effectiveness" rel="noopener noreferrer"&gt;Project Aristotle&lt;/a&gt; to find out what made their best teams tick, they looked at everything — educational background, personality types, seniority mix. The answer had almost nothing to do with &lt;em&gt;who&lt;/em&gt; was on the team and everything to do with &lt;em&gt;how&lt;/em&gt; they treated each other. Psychological safety came out as the single strongest predictor of team performance, ahead of every other factor they measured.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Anti-Patterns That Quietly Rot Team Culture
&lt;/h2&gt;

&lt;p&gt;Just like code smells, these are easy to miss day-to-day but corrosive over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The brilliant jerk.&lt;/strong&gt; A highly skilled developer who belittles others in reviews or design discussions. Tolerating this — even because they "ship fast" — tells the rest of the team that output matters more than how people are treated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weaponized &lt;code&gt;nit:&lt;/code&gt; comments.&lt;/strong&gt; Nitpicks used to assert dominance in a PR rather than to actually improve the code. The tell is volume and tone: constructive nitpicking is occasional and specific; weaponized nitpicking is constant and personal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating bugs as personal failure.&lt;/strong&gt; An unhandled exception in prod is a gap in your test suite, not a character flaw in whoever wrote the line. Teams that internalize this stop hiding bugs and start writing tests for them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Engineering a Safer Culture
&lt;/h2&gt;

&lt;p&gt;Safety doesn't happen by accident — it's a design pattern, and it takes the same intentionality as any other piece of architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Model vulnerability from the top
&lt;/h3&gt;

&lt;p&gt;Leads and staff engineers need to actually say &lt;em&gt;"I don't know,"&lt;/em&gt; &lt;em&gt;"I was wrong,"&lt;/em&gt; and &lt;em&gt;"I need help here"&lt;/em&gt; — out loud, in public channels, not just in 1:1s. When a senior engineer tells the story of the time they dropped a production database, it gives everyone else permission to be human.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Critique the code, not the person
&lt;/h3&gt;

&lt;p&gt;This is the single highest-leverage habit for review culture, and it's a small rewrite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- Your code is inefficient here.
&lt;/span&gt;&lt;span class="gi"&gt;+ Let's look at the time complexity of this loop — if the dataset
+ grows, we might hit a bottleneck. What do you think about a Map
+ instead of nested iteration?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same technical point, zero identity attached to it. The reviewer isn't softening the feedback — the feedback is exactly as direct. It's just aimed at the loop instead of the person who wrote it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Kill the async anxiety loop
&lt;/h3&gt;

&lt;p&gt;In remote and hybrid teams, a context-free message is its own kind of memory leak — it sits in someone's head consuming cycles until it's resolved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- We need to talk about your PR.
&lt;/span&gt;&lt;span class="gi"&gt;+ Hey, I left a couple of architecture questions on your PR —
+ no rush, let's chat about options at tomorrow's sync 👍
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix costs one extra sentence. The anxiety it prevents can cost an afternoon of someone's focus.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;We pour money into high availability, automated pipelines, and fault-tolerant infrastructure. But the most critical system any team runs is the human one underneath all of it. If your developers don't feel safe to fail, your software will eventually fail the same way — quietly, and in production.&lt;/p&gt;

&lt;p&gt;Psychological safety isn't the soft stuff. It's the infrastructure everything else runs on.&lt;/p&gt;

</description>
      <category>culture</category>
      <category>leadership</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>How to Thrive (Not Just Survive) as a Developer in the Age of AI</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Sat, 11 Jul 2026 12:54:36 +0000</pubDate>
      <link>https://dev.to/gaurav101/how-to-thrive-not-just-survive-as-a-developer-in-the-age-of-ai-3bdp</link>
      <guid>https://dev.to/gaurav101/how-to-thrive-not-just-survive-as-a-developer-in-the-age-of-ai-3bdp</guid>
      <description>&lt;p&gt;The narrative around Artificial Intelligence and software engineering has shifted dramatically. We are no longer asking &lt;em&gt;if&lt;/em&gt; AI will change development, but rather how we change &lt;em&gt;with&lt;/em&gt; it. &lt;/p&gt;

&lt;p&gt;If your value as a developer is tied solely to how fast you can churn out boilerplate code, write standard API endpoints, or memorize syntax, the landscape is becoming challenging. AI can do those things in seconds. However, this isn't a death sentence for the engineering career—it is an evolution. The industry is moving away from pure "code generation" and shifting toward &lt;strong&gt;system architecture, integration, and governance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To remain indispensable, you need to know exactly where to direct your energy and what pitfalls to avoid.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to Focus Your Energy
&lt;/h2&gt;

&lt;p&gt;To stay relevant, you must position yourself in the areas where AI struggles: high-level abstraction, complex contextual reasoning, and human leadership.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. System Design and Enterprise Architecture
&lt;/h3&gt;

&lt;p&gt;AI is excellent at writing isolated functions, but it struggles with massive, interconnected systems. Focus on how components interact at scale. Understanding how to slice a monolithic application into resilient microservices, orchestrate microfrontends, or design cloud-native solutions is where the high-value work lies. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Code Governance and Quality Assurance
&lt;/h3&gt;

&lt;p&gt;With AI generating code at unprecedented speeds, codebases are expanding faster than ever. The world doesn't just need people who can create code; it needs gatekeepers who can validate it. Your role will increasingly focus on setting quality standards, establishing robust CI/CD pipelines, and ensuring that AI-generated code adheres to strict security, compliance, and performance metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Mentorship and Team Leadership
&lt;/h3&gt;

&lt;p&gt;The influx of AI tools means junior engineers can produce code much earlier in their careers, but they often lack the foundational experience to spot subtle architectural flaws or security vulnerabilities. Senior developers must step up as leaders, guiding less experienced teammates on &lt;em&gt;why&lt;/em&gt; certain architectural patterns matter, preventing burnout, and maintaining engineering discipline within the team.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Deep Systems and Performance Optimization
&lt;/h3&gt;

&lt;p&gt;While AI can write functional code, it often writes resource-heavy or unoptimized code. Specializing in low-level systems programming, memory safety, and fine-tuning performance-critical applications gives you a massive edge. Knowing how to wring every ounce of efficiency out of a system remains a highly prized human skill.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Take Care of (The Pitfalls to Avoid)
&lt;/h2&gt;

&lt;p&gt;Staying relevant isn't just about learning new skills—it's also about avoiding the bad habits that AI tools can induce.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The "Copilot Crutch" Warning:&lt;/strong&gt; Relying too heavily on AI tools for basic problem-solving can cause your foundational engineering muscles to atrophy. If you don't understand the underlying logic of the code your AI assistant suggests, you cannot safely maintain or debug it when things break.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Watch out for Architectural Drift:&lt;/strong&gt; AI generates code based on local context (the file you are working on). It doesn't inherently understand your entire organization's long-term technical roadmap or governance model. Left unchecked, AI-assisted development can lead to a bloated, fragmented codebase.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Don't skip the "Why":&lt;/strong&gt; Always question AI suggestions. If a Large Language Model gives you an elegant solution, take a moment to understand &lt;em&gt;why&lt;/em&gt; it works before accepting the pull request. &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Guard your Domain Knowledge:&lt;/strong&gt; Technical skills matter, but understanding the business logic and user experience is what converts code into a successful product. AI doesn't know your customers; you do.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Evolution of the Developer Role
&lt;/h2&gt;

&lt;p&gt;To visualize this shift, look at how the daily responsibilities of a resilient software engineer are changing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traditional Developer Focus&lt;/th&gt;
&lt;th&gt;AI-Era Developer Focus&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Writing boilerplate, configurations, and repetitive unit tests.&lt;/td&gt;
&lt;td&gt;Designing system boundaries, security models, and data flows.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memorizing language syntax and API frameworks.&lt;/td&gt;
&lt;td&gt;Evaluating and integrating complex, multi-system dependencies.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixing syntax errors and basic debugging.&lt;/td&gt;
&lt;td&gt;Auditing AI-generated code for hidden vulnerabilities and tech debt.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functioning as an isolated individual contributor.&lt;/td&gt;
&lt;td&gt;Acting as a technical leader, mentor, and strategic translator for business needs.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Moving Forward
&lt;/h2&gt;

&lt;p&gt;The goal is to stop competing with AI at what it does best (speed and volume) and start leveraging it to do what humans do best (strategy, empathy, and holistic design). By shifting your mindset from being a "code writer" to a "software architect and custodian," you ensure that your skills remain not just relevant, but entirely essential to the future of technology.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>software</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Sick of App Store Ads? So I Built My Daughter Her Own Drawing PWA</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Thu, 02 Jul 2026 14:14:45 +0000</pubDate>
      <link>https://dev.to/gaurav101/building-a-ad-free-kid-friendly-drawing-pwa-with-my-daughter-and-google-ai-studio-13p4</link>
      <guid>https://dev.to/gaurav101/building-a-ad-free-kid-friendly-drawing-pwa-with-my-daughter-and-google-ai-studio-13p4</guid>
      <description>&lt;p&gt;"Daddy, another ad?"&lt;/p&gt;

&lt;p&gt;If you have young kids who use an iPad, you may know this problem.&lt;/p&gt;

&lt;p&gt;Last week, my daughter was using a free drawing app. She was happy and busy making her art. But every few minutes, a loud ad came on the screen. She could not skip it. It stopped her drawing again and again.&lt;/p&gt;

&lt;p&gt;After this happened many times, she looked at me and said:&lt;/p&gt;

&lt;p&gt;"I just want to draw. Can we make our own app without ads?"&lt;/p&gt;

&lt;p&gt;At first, I could have said that making an app takes too much time. But then I thought, why not try?&lt;/p&gt;

&lt;p&gt;So we made it a small weekend project.&lt;/p&gt;

&lt;p&gt;My daughter became the product boss. She asked for rainbow brushes, a big drawing space, fun sounds, and no pop-ups. I worked on the code.&lt;/p&gt;

&lt;p&gt;Together, we built this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unicorn-draw.vercel.app/" rel="noopener noreferrer"&gt;unicorn-draw.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tool that helped us build it fast was Google AI Studio with Gemini.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;p&gt;I wanted the app to be easy to use on an iPad. I also did not want to deal with the App Store.&lt;/p&gt;

&lt;p&gt;So I made it as a Progressive Web App, or PWA. This means it works like an app, but it runs in the browser.&lt;/p&gt;

&lt;p&gt;Here is what I used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML5 Canvas API for drawing&lt;/li&gt;
&lt;li&gt;CSS for big buttons and bright colors&lt;/li&gt;
&lt;li&gt;Service Worker so the app can work offline&lt;/li&gt;
&lt;li&gt;Web App Manifest so it can be added to the home screen&lt;/li&gt;
&lt;li&gt;Google AI Studio and Gemini to help write and improve the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because it is a PWA, my daughter can open it from the iPad home screen. It runs full screen. It has no ads, no tracking, and no hidden pop-ups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building with Google AI Studio
&lt;/h2&gt;

&lt;p&gt;Google AI Studio made the work much faster.&lt;/p&gt;

&lt;p&gt;First, I asked Gemini to make a simple drawing app using HTML5 canvas. I also asked it to support touch events, so it would work well on an iPad.&lt;/p&gt;

&lt;p&gt;Then my daughter tested the first version. She quickly asked for a magic rainbow brush and a simple clear button.&lt;/p&gt;

&lt;p&gt;I gave the code back to Gemini and asked it to add a rainbow brush. I also asked it to make the buttons look more fun for a drawing app.&lt;/p&gt;

&lt;p&gt;After that, I used Gemini to help create the PWA files, like &lt;code&gt;manifest.json&lt;/code&gt; and the service worker.&lt;/p&gt;

&lt;p&gt;In a short time, the app started to feel like a real tablet app.&lt;/p&gt;

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

&lt;p&gt;The project is open source.&lt;/p&gt;

&lt;p&gt;You can see the full code here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gaurav101/unicorn-draw" rel="noopener noreferrer"&gt;GitHub Repository: gaurav101/unicorn-draw&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Install It on an iPad or Phone
&lt;/h2&gt;

&lt;p&gt;You can add the app to your home screen in a few seconds.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://unicorn-draw.vercel.app/" rel="noopener noreferrer"&gt;unicorn-draw.vercel.app&lt;/a&gt; in your browser.&lt;/li&gt;
&lt;li&gt;On iPhone or iPad, tap the Share button. On Android, tap the three dots menu.&lt;/li&gt;
&lt;li&gt;Tap "Add to Home Screen".&lt;/li&gt;
&lt;li&gt;Open it from the home screen and start drawing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now your child has a simple drawing app with no ads.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  1. AI Helps You Build Faster
&lt;/h2&gt;

&lt;p&gt;Gemini did not just write code for me. It helped me move fast.&lt;/p&gt;

&lt;p&gt;Instead of spending time on small setup work, I could focus on how the app should feel for my daughter.&lt;/p&gt;

&lt;p&gt;The whole project took only a couple of hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Kids Can Learn That They Can Build Things
&lt;/h2&gt;

&lt;p&gt;The best part was not the app.&lt;/p&gt;

&lt;p&gt;The best part was seeing my daughter understand something important:&lt;/p&gt;

&lt;p&gt;Technology is not something we only have to use. If something is annoying or broken, we can try to make a better version.&lt;/p&gt;

&lt;p&gt;That was the real win.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gemini</category>
      <category>google</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Markdown to Styled HTML in Java</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Sun, 28 Jun 2026 08:22:14 +0000</pubDate>
      <link>https://dev.to/gaurav101/stop-fighting-your-css-framework-markdown-to-styled-html-in-java-5c06</link>
      <guid>https://dev.to/gaurav101/stop-fighting-your-css-framework-markdown-to-styled-html-in-java-5c06</guid>
      <description>&lt;p&gt;If you have ever built a Java application that converts Markdown to HTML—whether for a blog engine, a documentation site, or user-generated comments—you have likely run into a frustrating roadblock. &lt;/p&gt;

&lt;p&gt;You pull in a solid library like &lt;code&gt;commonmark-java&lt;/code&gt;, pass your Markdown string, and get perfectly valid semantic HTML blocks. But then you render it on the frontend and realize &lt;strong&gt;it looks completely unstyled.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Modern CSS frameworks like &lt;strong&gt;Tailwind CSS&lt;/strong&gt;, &lt;strong&gt;Bootstrap&lt;/strong&gt;, or &lt;strong&gt;Bulma&lt;/strong&gt; rely heavily on utility classes. They don't automatically style raw &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;, or &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; tags unless you wrap them in heavy global stylesheet overrides. To fix this in Java, you are usually forced to write verbose custom tag renderers, map complex attribute providers, or write messy string-replacement wrappers.&lt;/p&gt;

&lt;p&gt;That is exactly the problem &lt;a href="https://github.com/gaurav101/FluentMarkdown" rel="noopener noreferrer"&gt;FluentMarkdown&lt;/a&gt; solves. &lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What is FluentMarkdown?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/gaurav101/FluentMarkdown" rel="noopener noreferrer"&gt;FluentMarkdown&lt;/a&gt; is a lightweight, zero-boilerplate Java library built directly on top of &lt;code&gt;commonmark-java&lt;/code&gt;. It introduces a clean, fluent API that automatically injects the proper CSS framework classes into your HTML elements during the parsing phase.&lt;/p&gt;

&lt;p&gt;Instead of fighting your CSS framework, you can map your tags instantly using built-in presets or completely custom styles.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Installation
&lt;/h3&gt;

&lt;p&gt;The library is explicitly lightweight (only four core files) and requires &lt;strong&gt;Java 17 or later&lt;/strong&gt;. You can add it via Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.github.gaurav101&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;fluentmarkdown&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.4&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Quick Start: Use a Framework Preset
&lt;/h3&gt;

&lt;p&gt;If you use Tailwind, Bootstrap 5, or Bulma, FluentMarkdown has pre-mapped configurations ready to go.&lt;/p&gt;

&lt;p&gt;Here is how easily you can render fully-styled Tailwind HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.gaurav101.fluentmarkdown.Markdown&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"# Hello World\nThis is a paragraph."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// One fluent chain handles it all&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;tailwindHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Markdown&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                                      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withTailwind&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                                      &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toHtml&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tailwindHtml&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl font-extrabold tracking-tight mb-4 mt-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mb-4 leading-relaxed text-base"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This is a paragraph.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switching frameworks is as simple as swapping &lt;em&gt;.withTailwind()&lt;/em&gt; for &lt;em&gt;.withBootstrap()&lt;/em&gt; or &lt;em&gt;.withBulma()&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Advanced Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔒 Step 3: XSS Protection (Safe Mode)
&lt;/h3&gt;

&lt;p&gt;If you are processing untrusted user input (like blog comments), rendering raw HTML can expose your app to Cross-Site Scripting (XSS) attacks. FluentMarkdown includes a built-in .safe() modifier that strips out malicious inline scripts and raw HTML blocks seamlessly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;unsafeInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;script&amp;gt;alert('hack')&amp;lt;/script&amp;gt;\n\n# Safe Title"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;safeHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Markdown&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafeInput&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withTailwind&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;safe&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Strips dangerous HTML&lt;/span&gt;
                          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toHtml&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎨 Step 4: Custom Style Configurations
&lt;/h3&gt;

&lt;p&gt;Don't use a standard CSS framework? You can build an immutable StyleConfig to map your own internal design system classes to any HTML tag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.gaurav101.fluentmarkdown.StyleConfig&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;StyleConfig&lt;/span&gt; &lt;span class="n"&gt;myCustomConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StyleConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"custom-main-title"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"p"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"body-text text-muted"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"global-link"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;customHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Markdown&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withStyle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myCustomConfig&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toHtml&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔄 Step 5: Extend Existing Presets
&lt;/h3&gt;

&lt;p&gt;If you love the Tailwind preset but want to tweak just one or two elements (like changing the link color), you can merge and overwrite tags dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.github.gaurav101.fluentmarkdown.Presets&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;StyleConfig&lt;/span&gt; &lt;span class="n"&gt;modifiedTailwind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StyleConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mergeFrom&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Presets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tailwind&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Start with Tailwind defaults&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"text-indigo-600 underline"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Overwrite just the anchor tag&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎯Conclusion
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://central.sonatype.com/artifact/io.github.gaurav101/fluentmarkdown" rel="noopener noreferrer"&gt;FluentMarkdown&lt;/a&gt; provides a highly practical solution to a common backend UI problem. It keeps your Java code clean, readable, and perfectly married to modern frontend utilities.&lt;/p&gt;

&lt;p&gt;Give the project a look, try it out in your next Java project, and don't forget to drop a ⭐️ on the repository!&lt;/p&gt;

&lt;p&gt;👉 GitHub Repository: &lt;a href="https://github.com/gaurav101/FluentMarkdown" rel="noopener noreferrer"&gt;gaurav101/FluentMarkdown&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>html</category>
      <category>java</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Hidden Cost of the AI Hype</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Thu, 25 Jun 2026 15:55:00 +0000</pubDate>
      <link>https://dev.to/gaurav101/the-hidden-cost-of-the-ai-hype-2f5k</link>
      <guid>https://dev.to/gaurav101/the-hidden-cost-of-the-ai-hype-2f5k</guid>
      <description>&lt;p&gt;We talk a lot about what AI can build.&lt;/p&gt;

&lt;p&gt;Code generation. Faster prototypes. Automated debugging. One-shot apps. Entire products created in hours.&lt;/p&gt;

&lt;p&gt;And yes, AI is powerful.&lt;/p&gt;

&lt;p&gt;But there is a quieter cost we are not talking about enough:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI hype is starting to weaken the motivation to learn core engineering deeply.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That should worry us.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The "Why Bother?" Mindset
&lt;/h2&gt;

&lt;p&gt;When the dominant narrative says AI can generate code instantly, many engineers start asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why should I spend months mastering frameworks, architecture, databases, networking, or system design?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At first, that sounds practical. If a tool can help, why not use it?&lt;/p&gt;

&lt;p&gt;But there is a difference between using AI to move faster and using AI to avoid understanding.&lt;/p&gt;

&lt;p&gt;Core engineering is not just about writing code. It is about knowing why something works, where it breaks, how it scales, and how to fix it when the generated answer is wrong.&lt;/p&gt;

&lt;p&gt;If we skip that learning, we create engineers who can prompt systems but cannot reason deeply about systems.&lt;/p&gt;

&lt;p&gt;That is a dangerous tradeoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Funding and Praise Monopoly
&lt;/h2&gt;

&lt;p&gt;Right now, AI gets most of the attention.&lt;/p&gt;

&lt;p&gt;Budgets move toward AI. Leadership praises AI initiatives. Teams are pushed to add AI features even when the fundamentals are still weak.&lt;/p&gt;

&lt;p&gt;Meanwhile, excellent core engineering often goes unnoticed.&lt;/p&gt;

&lt;p&gt;The people improving reliability, performance, developer experience, infrastructure, security, and maintainability are still doing high-impact work. But in many places, that work is being treated as less exciting simply because it is not branded as AI.&lt;/p&gt;

&lt;p&gt;This creates pressure.&lt;/p&gt;

&lt;p&gt;Engineers feel they must pivot to AI, not always out of interest, but out of fear. Fear of being left behind. Fear of being replaced. Fear that their existing expertise is no longer valued.&lt;/p&gt;

&lt;p&gt;That is not innovation. That is anxiety disguised as progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The "AI-First" Discount
&lt;/h2&gt;

&lt;p&gt;There is another subtle problem.&lt;/p&gt;

&lt;p&gt;When someone builds something impressive today, the reaction is often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI probably generated that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That assumption discounts real skill.&lt;/p&gt;

&lt;p&gt;It ignores the planning, debugging, tradeoffs, refactoring, architecture, and judgment behind the work. AI may assist, but it does not automatically create good software.&lt;/p&gt;

&lt;p&gt;Great engineering still requires taste. Context. Discipline. Experience. The ability to make hard decisions when requirements are messy and systems are complex.&lt;/p&gt;

&lt;p&gt;When we assume every good output came from AI, we quietly devalue human craftsmanship.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Is an Accelerator, Not a Substitute
&lt;/h2&gt;

&lt;p&gt;AI can help us move faster.&lt;/p&gt;

&lt;p&gt;It can explain concepts, generate drafts, find bugs, write boilerplate, and help us explore ideas quickly.&lt;/p&gt;

&lt;p&gt;But AI is not a replacement for engineering fundamentals.&lt;/p&gt;

&lt;p&gt;If we stop learning the building blocks, we weaken the entire ecosystem AI depends on. Someone still needs to understand distributed systems. Someone still needs to design reliable APIs. Someone still needs to debug production failures at 2 AM. Someone still needs to know when the AI-generated solution is wrong.&lt;/p&gt;

&lt;p&gt;The future should not be "AI instead of engineers."&lt;/p&gt;

&lt;p&gt;It should be &lt;strong&gt;AI with stronger engineers&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Should Value
&lt;/h2&gt;

&lt;p&gt;We need to keep rewarding the work that keeps technology stable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strong system design&lt;/li&gt;
&lt;li&gt;Clean architecture&lt;/li&gt;
&lt;li&gt;Reliable infrastructure&lt;/li&gt;
&lt;li&gt;Secure software&lt;/li&gt;
&lt;li&gt;Maintainable codebases&lt;/li&gt;
&lt;li&gt;Deep debugging skills&lt;/li&gt;
&lt;li&gt;Thoughtful technical leadership&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can support this work, but it cannot replace the need for people who understand it deeply.&lt;/p&gt;

&lt;p&gt;The best engineers of the future will not be the ones who blindly rely on AI.&lt;/p&gt;

&lt;p&gt;They will be the ones who use AI wisely while continuing to sharpen their fundamentals.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>learning</category>
      <category>careerdevelopment</category>
    </item>
    <item>
      <title>Building a Safe, Local AI Coding Agent with Node.js</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Fri, 19 Jun 2026 03:57:12 +0000</pubDate>
      <link>https://dev.to/gaurav101/building-a-safe-local-ai-coding-agent-with-nodejs-46ol</link>
      <guid>https://dev.to/gaurav101/building-a-safe-local-ai-coding-agent-with-nodejs-46ol</guid>
      <description>&lt;p&gt;Welcome to the 4th article of the MCP and RAG with JS series.&lt;/p&gt;

&lt;p&gt;In this article, we will learn what AI agents are by building a practical, beginner-friendly coding agent in JavaScript. We will use a locally running LLM, Mistral on Ollama.&lt;/p&gt;

&lt;p&gt;You do not need any paid subscription or API key. Everything runs locally on your machine, so this is accessible for learning, testing, and experimenting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We Are Building
&lt;/h2&gt;

&lt;p&gt;We are building a local personal coding agent.&lt;/p&gt;

&lt;p&gt;It runs in the terminal and helps us understand a JavaScript project. It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;list project files&lt;/li&gt;
&lt;li&gt;read project files&lt;/li&gt;
&lt;li&gt;search text&lt;/li&gt;
&lt;li&gt;explain code&lt;/li&gt;
&lt;li&gt;find possible bugs&lt;/li&gt;
&lt;li&gt;propose code changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important safety rule is this:&lt;/p&gt;

&lt;p&gt;The agent can inspect files, but it does not directly edit them. If it wants to change something, it only returns a patch proposal for a human developer to review.&lt;/p&gt;

&lt;p&gt;So in simple words, we are building a small local coding assistant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Helps Us Learn
&lt;/h2&gt;

&lt;p&gt;AI agents can sound complicated, but most agent systems use a few common patterns.&lt;/p&gt;

&lt;p&gt;In this project, we will learn those patterns with plain JavaScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent loop: repeat until the model gives a final answer.&lt;/li&gt;
&lt;li&gt;Tool calling: let the model request specific JavaScript functions.&lt;/li&gt;
&lt;li&gt;Tool allowlist: only allow approved tools to run.&lt;/li&gt;
&lt;li&gt;System prompt: tell the model how it should behave.&lt;/li&gt;
&lt;li&gt;JSON action protocol: make the model respond with structured JSON.&lt;/li&gt;
&lt;li&gt;Model adapter: keep the Ollama HTTP code in one small file.&lt;/li&gt;
&lt;li&gt;Safety boundary: keep file access inside the project root.&lt;/li&gt;
&lt;li&gt;Human-in-the-loop changes: propose patches instead of applying them.&lt;/li&gt;
&lt;li&gt;Tests for safety: verify path traversal, large file, and missing file behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These same ideas appear in larger AI-agent frameworks. This project keeps them small enough to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Idea
&lt;/h2&gt;

&lt;p&gt;A normal chatbot usually works like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User asks question -&amp;gt; Model answers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent works more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User asks question
  -&amp;gt; Model decides what to do
  -&amp;gt; JavaScript runs a safe tool
  -&amp;gt; Model sees the tool result
  -&amp;gt; Model answers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model does not directly read your files or run commands. It asks for a tool, and your JavaScript code decides whether that tool is allowed.&lt;/p&gt;

&lt;p&gt;That is the main idea behind this project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;You can explore and clone the complete codebase in the &lt;a href="https://github.com/gaurav101/ai-experiment/tree/main/coding-agents" rel="noopener noreferrer"&gt;coding-agents GitHub repository.&lt;/a&gt;&lt;br&gt;
The important files are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
|-- package.json
|-- src
|   |-- cli.js
|   |-- agent.js
|   |-- ollama.js
|   `-- tools.js
`-- test
    `-- tools.test.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each file has a clear job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/cli.js&lt;/code&gt;: terminal entry point&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/agent.js&lt;/code&gt;: agent loop and tool dispatch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/ollama.js&lt;/code&gt;: local Ollama API client&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/tools.js&lt;/code&gt;: safe filesystem tools&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test/tools.test.js&lt;/code&gt;: safety and tool behavior tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1: CLI Entry Point
&lt;/h2&gt;

&lt;p&gt;The app starts in &lt;code&gt;src/cli.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It imports the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;runAgent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./agent.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it chooses the project root and model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OLLAMA_MODEL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mistral&lt;/span&gt;&lt;span class="dl"&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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;--root&lt;/code&gt; if the user provides it&lt;/li&gt;
&lt;li&gt;otherwise use the current folder&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;--model&lt;/code&gt; if provided&lt;/li&gt;
&lt;li&gt;otherwise use &lt;code&gt;OLLAMA_MODEL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;otherwise use &lt;code&gt;mistral&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CLI supports two modes.&lt;/p&gt;

&lt;p&gt;One-shot mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"Explain src/tools.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both cases, the CLI eventually calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;runAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verbose&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the CLI is only responsible for input and output. The real agent behavior lives in &lt;code&gt;runAgent&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2: Agent Loop
&lt;/h2&gt;

&lt;p&gt;The main function is in &lt;code&gt;src/agent.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;verbose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;At the start, it creates the available tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createTools&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./tools.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createTools&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passing &lt;code&gt;root&lt;/code&gt; is important. It tells the tools which folder they are allowed to inspect.&lt;/p&gt;

&lt;p&gt;Then the agent creates a message history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&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;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;buildSystemPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tools&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="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;goal&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;The &lt;code&gt;system&lt;/code&gt; message contains rules for the model. The &lt;code&gt;user&lt;/code&gt; message contains the developer's request.&lt;/p&gt;

&lt;p&gt;Then the agent runs a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;MAX_STEPS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateWithOllama&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// final answer or tool call&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;MAX_STEPS&lt;/code&gt; is set to &lt;code&gt;8&lt;/code&gt;, so the agent cannot loop forever.&lt;/p&gt;

&lt;p&gt;This loop is the heart of the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;messages -&amp;gt; prompt -&amp;gt; model -&amp;gt; action -&amp;gt; tool or final answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3: System Prompt
&lt;/h2&gt;

&lt;p&gt;The system prompt tells the model how to behave.&lt;/p&gt;

&lt;p&gt;In this project, the prompt says the model should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inspect files before making project-specific claims&lt;/li&gt;
&lt;li&gt;never claim a patch was applied&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;propose_patch&lt;/code&gt; only for suggested changes&lt;/li&gt;
&lt;li&gt;return exactly one JSON object&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also describes the available tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toolDescriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`- &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Parameters: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&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 lets the model know what it can ask for.&lt;/p&gt;

&lt;p&gt;The model must respond in one of two shapes.&lt;/p&gt;

&lt;p&gt;To call a tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"tool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"read_file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"src/example.js"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To finish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"final"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"answer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Your answer here."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple JSON action protocol. It is easy to understand because there is no hidden framework magic.&lt;/p&gt;

&lt;h2&gt;
  
  
  4: Local Model Adapter
&lt;/h2&gt;

&lt;p&gt;The file &lt;code&gt;src/ollama.js&lt;/code&gt; keeps the Ollama API call separate from the rest of the app.&lt;/p&gt;

&lt;p&gt;The default local URL is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DEFAULT_OLLAMA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://127.0.0.1:11434&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function sends the prompt to Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/api/generate`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-type&lt;/span&gt;&lt;span class="dl"&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;temperature&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;Then it returns the model text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&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 file has one job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prompt in -&amp;gt; Ollama HTTP request -&amp;gt; model response out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping this in one file makes it easier to swap models later.&lt;/p&gt;

&lt;h2&gt;
  
  
  5: Tool Calling
&lt;/h2&gt;

&lt;p&gt;After Ollama responds, the agent parses the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the model gives a final answer, the agent returns it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;final&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;answer&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;If the model asks for a tool, the agent checks whether that tool exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Unknown tool: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;allowedTools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tools&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="k"&gt;continue&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 is very important.&lt;/p&gt;

&lt;p&gt;The model cannot invent tools. It can only use tools that exist in the local JavaScript object.&lt;/p&gt;

&lt;p&gt;Then the agent runs the tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And sends the result back into the message history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;result&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;Now the model can use real project information instead of guessing.&lt;/p&gt;

&lt;p&gt;Example flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: Explain src/tools.js
Model: calls read_file
JavaScript: reads the file safely
Model: sees the file content
Model: gives final explanation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6: Safe Tools
&lt;/h2&gt;

&lt;p&gt;The tools live in &lt;code&gt;src/tools.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The project has four tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;list_files
read_file
search_text
propose_patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each tool has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt;: tells the model what it does&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parameters&lt;/code&gt;: tells the model what arguments it accepts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;run&lt;/code&gt;: the actual JavaScript function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Read a UTF-8 text file from inside the project root.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;File path relative to project root.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filePath&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// safe implementation&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;The tools are intentionally narrow.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;list_files&lt;/code&gt; lists files under the project root.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;read_file&lt;/code&gt; reads one text file if it is safe and not too large.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;search_text&lt;/code&gt; searches project files for a string or regex.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;propose_patch&lt;/code&gt; returns a patch proposal, but does not apply it.&lt;/p&gt;

&lt;p&gt;That last point matters. The model can suggest changes, but a human still reviews them.&lt;br&gt;
 ** use a safe regex engine if you are planning to expose the agent to external user inputs. ** &lt;/p&gt;
&lt;h2&gt;
  
  
  7: Path Safety With &lt;code&gt;safeResolve&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The most important safety function is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;safeResolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requestedPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;absolute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requestedPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;relative&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isAbsolute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Path escapes project root: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;requestedPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;absolute&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 blocks path traversal.&lt;/p&gt;

&lt;p&gt;For example, this should be allowed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/tools.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this should be blocked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;../outside.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the agent should only inspect the selected project folder. Model output is not trusted input, so every requested path goes through &lt;code&gt;safeResolve&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is one of the most important lessons in agent development:&lt;/p&gt;

&lt;p&gt;Give the model useful tools, but put real safety checks in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  8: Size Limits
&lt;/h2&gt;

&lt;p&gt;The tool layer also avoids reading huge files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MAX_READ_BYTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MAX_SEARCH_FILE_BYTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="nx"&gt;_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;read_file&lt;/code&gt; throws an error if a file is too large.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;search_text&lt;/code&gt; skips files that are too large.&lt;/p&gt;

&lt;p&gt;This protects the model context and keeps the agent responsive.&lt;/p&gt;

&lt;h2&gt;
  
  
  9: Patch Proposals, Not Auto-Edits
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;propose_patch&lt;/code&gt; tool returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;applied&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Patch proposal only. Review before applying.&lt;/span&gt;&lt;span class="dl"&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 is a human-in-the-loop design.&lt;/p&gt;

&lt;p&gt;The agent can help you think and propose changes, but it does not silently modify your files.&lt;/p&gt;

&lt;p&gt;For a beginner agent, this is a good safety tradeoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  10: Tests for Safety
&lt;/h2&gt;

&lt;p&gt;The project uses Vitest.&lt;/p&gt;

&lt;p&gt;From &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vitest run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test:watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vitest"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tests cover the dangerous parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;safeResolve&lt;/code&gt; allows normal paths&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;safeResolve&lt;/code&gt; blocks &lt;code&gt;../&lt;/code&gt; traversal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_files&lt;/code&gt; handles missing directories&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;read_file&lt;/code&gt; rejects missing paths and directories&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;read_file&lt;/code&gt; rejects large files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;search_text&lt;/code&gt; skips large files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;propose_patch&lt;/code&gt; returns &lt;code&gt;applied: false&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example traversal test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;safeResolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fixtureProjectRoot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../outside.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/escapes project root/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example large-file test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;large-read.txt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})).&lt;/span&gt;&lt;span class="nx"&gt;rejects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/too large to read safely/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tests are not just for correctness here. They protect the safety boundary of the agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete Request Flow
&lt;/h2&gt;

&lt;p&gt;If you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"Explain src/tools.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;src/cli.js&lt;/code&gt; receives the request.&lt;/li&gt;
&lt;li&gt;It calls &lt;code&gt;runAgent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/agent.js&lt;/code&gt; creates safe tools.&lt;/li&gt;
&lt;li&gt;The system prompt describes the rules and tools.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/ollama.js&lt;/code&gt; sends the prompt to local Ollama.&lt;/li&gt;
&lt;li&gt;The model returns a JSON action.&lt;/li&gt;
&lt;li&gt;If it asks for a tool, the agent checks the allowlist.&lt;/li&gt;
&lt;li&gt;The tool runs with safety checks.&lt;/li&gt;
&lt;li&gt;The tool result goes back to the model.&lt;/li&gt;
&lt;li&gt;The model returns a final answer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is an AI agent in practical terms.&lt;/p&gt;

&lt;p&gt;It is an LLM connected to a controlled loop, safe tools, and clear rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Run It
&lt;/h2&gt;

&lt;p&gt;Requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 18 or newer&lt;/li&gt;
&lt;li&gt;Ollama installed&lt;/li&gt;
&lt;li&gt;Mistral pulled locally&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pull the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull mistral
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask one question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"Explain src/agent.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inspect another project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--root&lt;/span&gt; /path/to/project &lt;span class="s2"&gt;"Find bugs in the main CLI file"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run syntax checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What to Remember
&lt;/h2&gt;

&lt;p&gt;An AI agent is not just an LLM.&lt;/p&gt;

&lt;p&gt;An AI agent is usually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LLM + loop + tools + context + safety rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the CLI gets the user request&lt;/li&gt;
&lt;li&gt;the agent loop manages steps&lt;/li&gt;
&lt;li&gt;Ollama provides the local model&lt;/li&gt;
&lt;li&gt;tools provide controlled abilities&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;safeResolve&lt;/code&gt; protects file access&lt;/li&gt;
&lt;li&gt;tests protect the safety behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model can request actions, but JavaScript decides what actually runs.&lt;/p&gt;

&lt;p&gt;That is the key idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project is intentionally small, but it teaches the foundation behind many larger agent systems.&lt;/p&gt;

&lt;p&gt;Once you understand this version, you can explore more advanced ideas like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;memory across chat turns&lt;/li&gt;
&lt;li&gt;streaming model output&lt;/li&gt;
&lt;li&gt;richer tool schemas&lt;/li&gt;
&lt;li&gt;patch validation&lt;/li&gt;
&lt;li&gt;confirmation-based patch applying&lt;/li&gt;
&lt;li&gt;MCP tools&lt;/li&gt;
&lt;li&gt;RAG over larger codebases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the core idea stays the same:&lt;/p&gt;

&lt;p&gt;Mistral is a good simple default for learning, but when you are building stronger coding agents, coding-focused models usually give better results. Good options to try are qwen2.5-coder, deepseek-coder, and Gemma.&lt;/p&gt;

&lt;p&gt;Build useful tools, keep them narrow, and let your application code enforce the safety boundaries.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>SOLSTICE: Planetary Balance</title>
      <dc:creator>Gaurav Kumar Singh</dc:creator>
      <pubDate>Tue, 16 Jun 2026 04:17:53 +0000</pubDate>
      <link>https://dev.to/gaurav101/solstice-planetary-balance-1hec</link>
      <guid>https://dev.to/gaurav101/solstice-planetary-balance-1hec</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Solstice Balance is an interactive 3D calibration simulator where the player stabilizes Earth's obliquity (target 23.44°) and rotational speed to prevent a simulated thermal collapse.&lt;br&gt;
Players use thruster-style controls to correct tilt and spin while reacting to procedurally generated cosmic disturbances (solar flares, gravitational tides, meteors). &lt;br&gt;
The goal was to make a tactile, physics-driven experience that ties to the June Solstice theme—balancing seasonal geometry with emergent hazards.&lt;/p&gt;
&lt;h2&gt;
  
  
  Game Demo
&lt;/h2&gt;

&lt;p&gt;Play the live demo: &lt;a href="https://solstice-game.vercel.app/" rel="noopener noreferrer"&gt;https://solstice-game.vercel.app/&lt;/a&gt;&lt;br&gt;
(Recommended: open in a desktop browser for best WebGL and audio support.)&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://solstice-game.vercel.app/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;solstice-game.vercel.app&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;Full source code and development history: &lt;a href="https://github.com/gaurav101/solstice-game" rel="noopener noreferrer"&gt;https://github.com/gaurav101/solstice-game&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI Assistance:&lt;/strong&gt; Utilized Google Gemini to pair-program, debug complex WebGL contexts, and rapidly iterate on the core physics calculations and WebGL Sound generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framework:&lt;/strong&gt; React + TypeScript with Vite for fast iteration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3D &amp;amp; Physics:&lt;/strong&gt; Three.js for rendering and &lt;code&gt;cannon-es&lt;/code&gt; for rigid-body physics to simulate tilt, spin, and meteor impacts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio:&lt;/strong&gt; WebAudio-based synth engine and sampled effects for real-time atmospheric feedback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI:&lt;/strong&gt; Tailwind CSS for a clean, rapid HUD layout; React state syncs real-time telemetry (score, alignment, RPM) seamlessly with the WebGL loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Optimization:&lt;/strong&gt; Employed procedural textures, batched particle systems, and defensive resource disposal to prevent memory leaks across scene restarts. 
## How to play the game 
Below is your official flight manual to successfully calibrate Earth's rotation and orientation, countering severe space weather, and maintaining life-supporting equilibrium.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Notable design choice:&lt;/em&gt; The game loop runs inside a single &lt;code&gt;requestAnimationFrame&lt;/code&gt; driven effect that cleanly tears down Three/Cannon resources when switching game states to completely avoid leaking WebGL contexts.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Play the Game  (&lt;a href="https://solstice-game.vercel.app/" rel="noopener noreferrer"&gt;https://solstice-game.vercel.app/&lt;/a&gt;)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🛰️ 1. The Core Objective
&lt;/h3&gt;

&lt;p&gt;Your active task is to guide and maintain Earth's planetary parameters in specified target alignment zones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Target Axial Obliquity:&lt;/strong&gt; &lt;strong&gt;23.0° to 23.9°&lt;/strong&gt; (aiming precisely for the natural June Solstice angle of &lt;strong&gt;23.44°&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Target Rotational Velocity (Spin):&lt;/strong&gt; &lt;strong&gt;1.0 to 2.5 RPM&lt;/strong&gt; (Revolutions Per Minute).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Planetary Ecosystem Integrity:&lt;/strong&gt; Must remain above &lt;strong&gt;0%&lt;/strong&gt;. Integrity decays rapidly any second Earth remains outside optimal thresholds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎮 2. Control Layout
&lt;/h3&gt;

&lt;p&gt;Counter-act deep space gravitational pull and harsh solar winds by applying immediate corrective torque.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Keyboard Input&lt;/th&gt;
&lt;th&gt;Control Board Thruster&lt;/th&gt;
&lt;th&gt;Operational Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;W&lt;/code&gt; or &lt;code&gt;▲ Up&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Pitch Forward&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tilts Earth's axis forward pointing towards the Sun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;S&lt;/code&gt; or &lt;code&gt;▼ Down&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Pitch Backward&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tilts Earth's axis backward away from the Sun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;A&lt;/code&gt; or &lt;code&gt;◀ Left&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Spin Faster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Speeds up the Earth's west-to-east spin velocity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;D&lt;/code&gt; or &lt;code&gt;▶ Right&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Spin Slower&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Applies electromagnetic dragging to slow rotation down&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  ☀️ 3. Key Calibration Rules
&lt;/h3&gt;

&lt;h4&gt;
  
  
  📍 The Solstice sweet spot (23.44°)
&lt;/h4&gt;

&lt;p&gt;When Earth is tilted at &lt;strong&gt;23.44°&lt;/strong&gt;, the North Pole is angled perfectly toward the Sun. In this position, you will see a bright circular sunlit ring over the Arctic region (the Midnight Sun) while the Antarctic Circle remains in winter shadow. This is the &lt;strong&gt;June Solstice Threshold&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Maintaining the axis inside the green &lt;strong&gt;23.0° - 23.9°&lt;/strong&gt; band raises your &lt;strong&gt;Calibration Accuracy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Every second spent inside optimal zones awards &lt;strong&gt;Equilibrium Points&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🌀 The Rotational Band (1.0 to 2.5 RPM)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Static Risk (Spin below 0.3 RPM):&lt;/strong&gt; If the Earth stops spinning, one side of the planet is cooked under permanent radiation, and the other freezes in absolute darkness. &lt;em&gt;Ecosystem integrity will drop exponentially!&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Erosion Risk (Spin above 3.5 RPM):&lt;/strong&gt; Rotating too fast generates cosmic atmospheric drag that will tear away the ozone layers. &lt;em&gt;Ecosystem integrity drops rapidly.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚨 4. Galactic Disturbance Hazards
&lt;/h3&gt;

&lt;p&gt;The orbital field is subject to unexpected external solar interferences that will knock you out of alignment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Coronal Mass Ejections (Solar Flares):&lt;/strong&gt; Strong electromagnetic storms that apply extreme pitch forces, abruptly throwing off the planetary tilt obliquity.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Atmospheric Gravitational Tides:&lt;/strong&gt; Tidal fluctuations that can speed up or slow down Earth's spin speed.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Meteor Incursions:&lt;/strong&gt; Direct strikes that transfer kinetic momentum, rotating or tipping Earth suddenly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Listen for the Audio Synth’s pitch and tempo:&lt;/em&gt; The onboard audio system uses warning buzzers and frantic tempo modulation to signal when parameters are entering danger thresholds.&lt;/p&gt;




&lt;h3&gt;
  
  
  🏆 5. Tips for Pro-Commanders
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Pulsed Thrusters over Static Holding:&lt;/strong&gt; Do not hold down thruster buttons endlessly. Tap controls in short bursts to counteract drift, letting the friction settle the planet in the optimal zone.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Balance First, Tilt Second:&lt;/strong&gt; If you are knocked completely off-course, prioritize bringing the planetary spin back into the &lt;strong&gt;1.0 - 2.5 RPM band&lt;/strong&gt; first to stop thermal decay, then nudge the obliquity to the target solstice angle.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Observe the Shaders:&lt;/strong&gt; Watch the gorgeous daytime sunlight and glittering nightly city light shaders. If you see city light configurations rotating either too fast or not at all, immediately act!&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Initialize engine calibration, steady the core, and save the Solstice!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Google AI Usage:&lt;/strong&gt; Google Gemini was instrumental in prototyping the initial graphics setup, debugging tricky 3D coordinate transformations, and ensuring the physics-driven gameplay integrated perfectly with React's state management.&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>devchallenge</category>
      <category>gamechallenge</category>
      <category>gamedev</category>
    </item>
  </channel>
</rss>
