<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alberto Barrago</title>
    <description>The latest articles on Forem by Alberto Barrago (@albz).</description>
    <link>https://forem.com/albz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1671227%2F147fd596-8201-48ff-80d4-ca55d1f2e4d8.png</url>
      <title>Forem: Alberto Barrago</title>
      <link>https://forem.com/albz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/albz"/>
    <language>en</language>
    <item>
      <title>I Built My Own Diagramming Tool</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Thu, 09 Apr 2026 14:57:26 +0000</pubDate>
      <link>https://forem.com/albz/i-built-my-own-diagramming-tool-no-framework-no-runtime-just-canvas-3cn1</link>
      <guid>https://forem.com/albz/i-built-my-own-diagramming-tool-no-framework-no-runtime-just-canvas-3cn1</guid>
      <description>&lt;p&gt;Hey! I’ve been working on Markasso, a lightweight drawing and diagramming tool. Built entirely from scratch with vanilla JS and Canvas 2D API. No frameworks, no libraries, nothing.&lt;/p&gt;

&lt;p&gt;Why I built it: In this AI era where you can generate anything in seconds, I wanted to actually build something myself from the ground up. Understand (or try to do it) every line, every pixel, every math formula behind it. &lt;/p&gt;

&lt;p&gt;My grandmother was a math teacher so I guess the stubbornness runs in the family, but I’ll be honest, Claude helped me a lot when the geometry got tricky and Lorenzo Cataldi with the UI.&lt;/p&gt;

&lt;p&gt;Everything is hand-rolled: pure Canvas API (no SVG), a Redux-like state management with immutable state and action-based updates, hit detection, bounding boxes, transform handles, undo/redo via action stack. Single user, runs entirely in the browser.&lt;/p&gt;

&lt;p&gt;It’s also packed with little things I cared about: full keyboard shortcuts, multi-language support, a magnetic grid for snapping, and custom format export. I wanted it to feel like a real tool, not just a tech demo.&lt;/p&gt;

&lt;p&gt;The hardest part was making resize handles feel natural when you’re doing all the geometry yourself.&lt;br&gt;
Once you try building this stuff from scratch you really start to appreciate what the Excalidraw team has done.&lt;/p&gt;

&lt;p&gt;&lt;a href="//Markasso.it"&gt;Make a trip ^^&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://github.com/AlbertoBarrago/Markasso" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love to hear your feedback, especially on UX and what features you’d want to see next!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>sideprojects</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Fix: Eliminating Double Async Validation in TanStack Form &amp; Zod</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Tue, 17 Feb 2026 18:10:16 +0000</pubDate>
      <link>https://forem.com/albz/fix-eliminating-double-async-validation-in-tanstack-form-zod-2dc</link>
      <guid>https://forem.com/albz/fix-eliminating-double-async-validation-in-tanstack-form-zod-2dc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A practical pattern to prevent duplicate API calls and race conditions&lt;br&gt;
in complex React forms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When building production-grade forms with &lt;strong&gt;TanStack Form&lt;/strong&gt; and &lt;strong&gt;Zod&lt;/strong&gt;,&lt;br&gt;
especially in flows involving &lt;strong&gt;side effects&lt;/strong&gt; (e.g., OTP generation,&lt;br&gt;
user verification), you may encounter an elusive bug:&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Async validation running twice on submit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This can lead to duplicated API calls, inconsistent state, and poor user&lt;br&gt;
experience.&lt;/p&gt;

&lt;p&gt;In this article, we explore: - Why this happens - How to fix it&lt;br&gt;
reliably - How to harden your form logic for real-world scale&lt;/p&gt;


&lt;h2&gt;
  
  
  🚨 The Problem: Double Async Execution
&lt;/h2&gt;

&lt;p&gt;A known issue in TanStack &lt;a href="https://github.com/TanStack/form/issues/1431" rel="noopener noreferrer"&gt;Issue #1431&lt;/a&gt; causes async&lt;br&gt;
validation (&lt;code&gt;superRefine&lt;/code&gt;) to execute multiple times during submission.&lt;/p&gt;
&lt;h3&gt;
  
  
  Typical Setup
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;defaultValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;myZodSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// async superRefine&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;onSubmit&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="nx"&gt;value&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendOtp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❌ may be called twice&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Why It's Dangerous
&lt;/h3&gt;

&lt;p&gt;In flows like OTP authentication: - Multiple requests generate&lt;br&gt;
&lt;strong&gt;different codes&lt;/strong&gt; - First code becomes invalid - Users get stuck&lt;/p&gt;

&lt;p&gt;👉 This is not just inefficiency --- it's a &lt;strong&gt;critical UX bug&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 Root Cause
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  TanStack Form may trigger validation multiple times internally&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;superRefine&lt;/code&gt; contains &lt;strong&gt;side effects&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  Validation ≠ Pure function anymore&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This breaks the expectation that validation is idempotent&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ The Solution: Take Back Control
&lt;/h2&gt;

&lt;p&gt;We fix the issue with &lt;strong&gt;3 architectural decisions&lt;/strong&gt;:&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Manual Validation with &lt;code&gt;safeParseAsync&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Avoid relying on automatic validation during submission.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="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;myZodSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParseAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✔ Prevents double execution&lt;br&gt;
✔ Gives full control over validation lifecycle&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Prevent Re-entrancy with &lt;code&gt;useRef&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;React state is not always fast enough to block rapid interactions.&lt;/p&gt;

&lt;p&gt;Use a &lt;strong&gt;low-level semaphore&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isSubmittingRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Decouple Side Effects
&lt;/h2&gt;

&lt;p&gt;Never trigger API calls inside validation.&lt;/p&gt;

&lt;p&gt;👉 Validation must remain pure&lt;br&gt;
👉 Side effects go inside controlled submit flow&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Full Implementation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isSubmittingRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isSubmittingRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;isSubmittingRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Manual validation&lt;/span&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;myZodSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParseAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&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;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// map errors if needed&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Execute side effect ONCE&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;triggerOtpRequest&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;isSubmittingRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌐 Network Layer Optimization
&lt;/h2&gt;

&lt;p&gt;During testing, another issue emerged: 👉 &lt;strong&gt;unwanted re-fetching&lt;br&gt;
disrupting UX&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix your QueryClient config:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;QueryClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;defaultOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;staleTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;refetchOnWindowFocus&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="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why it matters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Users switch tabs to check OTP&lt;/li&gt;
&lt;li&gt;  Returning triggers refetch&lt;/li&gt;
&lt;li&gt;  UI state resets unexpectedly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Disable it for critical flows&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Production Insights
&lt;/h2&gt;

&lt;p&gt;From a real-world system serving high traffic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Small validation bugs can scale into &lt;strong&gt;massive API waste&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  Race conditions are often &lt;strong&gt;invisible locally&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  Libraries are not always safe for &lt;strong&gt;side-effect-heavy flows&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Always design defensively&lt;/p&gt;




&lt;h2&gt;
  
  
  🔑 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validation must be pure&lt;/strong&gt;&lt;br&gt;
Avoid side effects inside &lt;code&gt;superRefine&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Control execution manually&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;safeParseAsync&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prevent race conditions&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;useRef&lt;/code&gt; as a semaphore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tune network behavior&lt;/strong&gt;&lt;br&gt;
Disable &lt;code&gt;refetchOnWindowFocus&lt;/code&gt; when needed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;If your validation triggers APIs, you are no longer just validating &lt;br&gt;
you are orchestrating &lt;strong&gt;stateful workflows&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 Treat it like backend logic, not just form validation.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Discussion
&lt;/h2&gt;

&lt;p&gt;Have you experienced similar issues with async validation or race&lt;br&gt;
conditions in React forms?&lt;/p&gt;

&lt;p&gt;Let's discuss 👇&lt;/p&gt;




</description>
      <category>react</category>
      <category>architecture</category>
      <category>frontend</category>
    </item>
    <item>
      <title>RefAIne: Transform Casual Prompts into Expert-Level AI Instructions</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Mon, 05 Jan 2026 22:42:48 +0000</pubDate>
      <link>https://forem.com/albz/refaine-transform-casual-prompts-into-expert-level-ai-instructions-3d9c</link>
      <guid>https://forem.com/albz/refaine-transform-casual-prompts-into-expert-level-ai-instructions-3d9c</guid>
      <description>&lt;p&gt;A free, open-source FastAPI microservice that converts simple prompts into detailed, production-ready AI instructions. Supports multiple LLM providers including Claude, OpenAI, Ollama, and Groq.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Getting AI assistants to understand exactly what you need often requires multiple iterations. When you ask to "create a REST API," you might get a basic example when you actually need authentication, error handling, validation, and production-ready code.&lt;/p&gt;

&lt;p&gt;This gap between brief prompts and detailed requirements costs developers significant time in refinement cycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;RefAIne is a FastAPI microservice (approximately 145 lines) that transforms casual prompts into comprehensive engineering instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Input:&lt;/strong&gt; &lt;code&gt;"make a function to sort a list"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Output:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a Python function that sorts a list with the following requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Function signature: Accept a list of comparable elements as input&lt;/li&gt;
&lt;li&gt;Return a new sorted list (do not modify the original)&lt;/li&gt;
&lt;li&gt;Use Python's built-in sorting (efficient O(n log n) Timsort)&lt;/li&gt;
&lt;li&gt;Add type hints and docstrings with examples&lt;/li&gt;
&lt;li&gt;Include error handling for None or non-list inputs&lt;/li&gt;
&lt;li&gt;Handle edge cases: empty list, single element, already sorted&lt;/li&gt;
&lt;li&gt;Make it generic to work with any comparable types&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Provide clean, PEP 8 compliant code with tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;RefAIne automatically adds technical context, specificity, best practices, and edge case considerations.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Free Testing Options
&lt;/h3&gt;

&lt;p&gt;Test locally with Ollama at no cost before using paid APIs. No credit card or API key required for initial testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple Provider Support
&lt;/h3&gt;

&lt;p&gt;Switch between LLM providers using a single environment variable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ollama (free, local, private)&lt;/li&gt;
&lt;li&gt;Groq (free tier available)&lt;/li&gt;
&lt;li&gt;Anthropic Claude (paid)&lt;/li&gt;
&lt;li&gt;OpenAI (paid)&lt;/li&gt;
&lt;li&gt;Any OpenAI-compatible API&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production Ready
&lt;/h3&gt;

&lt;p&gt;Includes Docker configuration, comprehensive documentation, and environment-based configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Focused Design
&lt;/h3&gt;

&lt;p&gt;Single-purpose service with one endpoint and minimal dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  About the Project
&lt;/h2&gt;

&lt;p&gt;RefAIne was created by &lt;a href="https://github.com/AlbertoBarrago" rel="noopener noreferrer"&gt;Alberto Barrago&lt;/a&gt; to automate the prompt refinement process. The project is open-source under the MIT license, allowing use in commercial projects without restrictions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supporting Development
&lt;/h2&gt;

&lt;p&gt;RefAIne is free to use and will remain so. However, maintaining open-source software requires ongoing investment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server costs for testing and demonstrations&lt;/li&gt;
&lt;li&gt;API credits for development across multiple providers&lt;/li&gt;
&lt;li&gt;Time for bug fixes, features, and support&lt;/li&gt;
&lt;li&gt;Documentation and example creation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If RefAIne has been useful in your work, consider supporting the project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Star the repository: &lt;a href="https://github.com/AlbertoBarrago/RefAIne" rel="noopener noreferrer"&gt;github.com/AlbertoBarrago/RefAIne&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Contribute financially via GitHub Sponsors or donation platforms&lt;/li&gt;
&lt;li&gt;Share the project with other developers&lt;/li&gt;
&lt;li&gt;Report issues or contribute code improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Financial support helps maintain active development, add new provider integrations, improve refinement quality, and respond to community needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone repository&lt;/span&gt;
git clone https://github.com/AlbertoBarrago/RefAIne.git
&lt;span class="nb"&gt;cd &lt;/span&gt;RefAIne

&lt;span class="c"&gt;# Install and configure Ollama (for free local testing)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://ollama.com/install.sh | sh
ollama pull llama3.1

&lt;span class="c"&gt;# Set up environment&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
LLM_PROVIDER=openai
OPENAI_BASE_URL=http://localhost:11434/v1
OPENAI_API_KEY=ollama
OPENAI_MODEL=llama3.1
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Install and run&lt;/span&gt;
uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; pyproject.toml
uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;

&lt;span class="c"&gt;# Test the endpoint&lt;/span&gt;
curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8000/refine &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"prompt": "create a REST API"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive API documentation is available at &lt;code&gt;http://localhost:8000/docs&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Repository: &lt;a href="https://github.com/AlbertoBarrago/RefAIne" rel="noopener noreferrer"&gt;github.com/AlbertoBarrago/RefAIne&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Issue Tracker: Report bugs or request features&lt;/li&gt;
&lt;li&gt;Documentation: Included in repository README&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Contributions and feedback are welcome.&lt;/p&gt;

</description>
      <category>python</category>
      <category>fastapi</category>
      <category>ai</category>
    </item>
    <item>
      <title>WIR - What Is Running: A CLI Tool in C to Inspect Processes and Ports</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Tue, 30 Dec 2025 20:28:59 +0000</pubDate>
      <link>https://forem.com/albz/wir-what-is-running-a-cli-tool-in-c-to-inspect-processes-and-ports-5hdi</link>
      <guid>https://forem.com/albz/wir-what-is-running-a-cli-tool-in-c-to-inspect-processes-and-ports-5hdi</guid>
      <description>&lt;p&gt;I recently released &lt;strong&gt;wir&lt;/strong&gt; (What Is Running), a command-line tool written in C to inspect what's running on specific ports and get detailed process information. A project born from a practical need that turned into an opportunity to explore system programming in C.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;How many times have you had a port occupied without knowing which process is using it? Or needed to trace a process hierarchy to understand who spawned what? We usually resort to combinations of &lt;code&gt;lsof&lt;/code&gt;, &lt;code&gt;netstat&lt;/code&gt;, and &lt;code&gt;ps&lt;/code&gt;, but why not have everything in a single command?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;wir&lt;/code&gt; is a cross-platform tool (macOS and Linux) that allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discover which process is using a specific port&lt;/li&gt;
&lt;li&gt;Get detailed information about a PID&lt;/li&gt;
&lt;li&gt;Visualize the complete ancestry tree of a process&lt;/li&gt;
&lt;li&gt;List all running processes&lt;/li&gt;
&lt;li&gt;View a process's environment variables&lt;/li&gt;
&lt;li&gt;Output in normal, short, JSON, or tree format&lt;/li&gt;
&lt;li&gt;Receive security warnings for potentially risky configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Who's using port 8080?&lt;/span&gt;
wir &lt;span class="nt"&gt;--port&lt;/span&gt; 8080

&lt;span class="c"&gt;# Info about a specific process&lt;/span&gt;
wir &lt;span class="nt"&gt;--pid&lt;/span&gt; 1234

&lt;span class="c"&gt;# Show the process ancestry tree&lt;/span&gt;
wir &lt;span class="nt"&gt;--pid&lt;/span&gt; 1234 &lt;span class="nt"&gt;--tree&lt;/span&gt;

&lt;span class="c"&gt;# JSON output for scripting&lt;/span&gt;
wir &lt;span class="nt"&gt;--port&lt;/span&gt; 3000 &lt;span class="nt"&gt;--json&lt;/span&gt;

&lt;span class="c"&gt;# List all processes (short format)&lt;/span&gt;
wir &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--short&lt;/span&gt;

&lt;span class="c"&gt;# Security warnings only&lt;/span&gt;
wir &lt;span class="nt"&gt;--port&lt;/span&gt; 8080 &lt;span class="nt"&gt;--warnings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;The project is structured in a modular way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform abstraction layer&lt;/strong&gt;: handles differences between Linux (&lt;code&gt;/proc&lt;/code&gt; parsing) and macOS (&lt;code&gt;libproc&lt;/code&gt; and &lt;code&gt;sysctl&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output formatting&lt;/strong&gt;: supports multiple display modes without duplicating logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent error handling&lt;/strong&gt;: every allocation is checked, every resource is freed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict memory management&lt;/strong&gt;: no leaks, no undefined behavior&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Writing &lt;code&gt;wir&lt;/code&gt; was an excellent opportunity to practice fundamental concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;System programming&lt;/strong&gt;: interfacing with &lt;code&gt;/proc&lt;/code&gt;, system calls, process management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform development&lt;/strong&gt;: conditional compilation and different APIs for each OS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety in C&lt;/strong&gt;: manual memory management without a garbage collector&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build systems&lt;/strong&gt;: Makefile with automatic platform detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API design&lt;/strong&gt;: clean and composable interface&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  I Don't Memorize Commands
&lt;/h2&gt;

&lt;p&gt;As my approach goes: I'm not interested in memorizing the exact &lt;code&gt;lsof&lt;/code&gt; or &lt;code&gt;netstat&lt;/code&gt; commands. I prefer understanding the underlying architecture and building tools that solve the problem more elegantly. &lt;code&gt;wir&lt;/code&gt; isn't just a wrapper, it's an abstraction that hides the complexity of OS differences.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future
&lt;/h2&gt;

&lt;p&gt;The project is open to extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UDP port support&lt;/li&gt;
&lt;li&gt;Advanced process filtering&lt;/li&gt;
&lt;li&gt;Support for other OSes (BSD, etc.)&lt;/li&gt;
&lt;li&gt;Performance optimizations&lt;/li&gt;
&lt;li&gt;Additional output formats&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/AlbertoBarrago/wir" rel="noopener noreferrer"&gt;wir&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a learning project, so feel free to experiment and extend it. Building system tools in C is a great way to understand what's really happening under the hood.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build and install&lt;/span&gt;
brew tap AlbertoBarrago/tap
brew &lt;span class="nb"&gt;install &lt;/span&gt;wir

&lt;span class="c"&gt;# Start using it&lt;/span&gt;
wir &lt;span class="nt"&gt;--port&lt;/span&gt; 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>c</category>
      <category>tooling</category>
      <category>cli</category>
    </item>
    <item>
      <title>Neovim + COQ + Mason + LSP: Mini Guide</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Mon, 17 Nov 2025 22:16:29 +0000</pubDate>
      <link>https://forem.com/albz/neovim-coq-mason-lsp-mini-guide-246h</link>
      <guid>https://forem.com/albz/neovim-coq-mason-lsp-mini-guide-246h</guid>
      <description>&lt;p&gt;This guide explains how to properly set up &lt;strong&gt;COQ.nvim&lt;/strong&gt; autocomplete&lt;br&gt;
with &lt;strong&gt;Mason&lt;/strong&gt; and &lt;strong&gt;LSP servers&lt;/strong&gt; in Neovim. It includes the most&lt;br&gt;
common pitfalls and a working configuration.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔧 1. Install Required Plugins
&lt;/h2&gt;

&lt;p&gt;Make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;ms-jpq/coq_nvim&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;ms-jpq/coq.artifacts&lt;/code&gt; (optional, extra completions)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;williamboman/mason.nvim&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;williamboman/mason-lspconfig.nvim&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;neovim/nvim-lspconfig&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example (lazy.nvim):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"ms-jpq/coq_nvim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"coq"&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="s2"&gt;"ms-jpq/coq.artifacts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"artifacts"&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="s2"&gt;"williamboman/mason.nvim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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="s2"&gt;"williamboman/mason-lspconfig.nvim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"neovim/nvim-lspconfig"&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;h2&gt;
  
  
  ⚡ 2. Enable COQ Auto-Start
&lt;/h2&gt;

&lt;p&gt;COQ does not start automatically unless configured.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;vim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;coq_settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;auto_start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'shut-up'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, use manually later:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:COQnow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  🧠 3. Correct Working LSP + COQ Setup
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"mason"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;coq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"coq"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"mason-lspconfig"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="n"&gt;ensure_installed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"pyright"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jdtls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dockerls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"elixirls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ts_ls"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;automatic_installation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="n"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lspconfig"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;server_name&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;coq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lsp_ensure_capabilities&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"elixirls"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"lspconfig"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;elixirls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;coq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lsp_ensure_capabilities&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;debounce_text_changes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="n"&gt;elixirLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;dialyzerEnabled&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="n"&gt;fetchDeps&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;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;end&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;h2&gt;
  
  
  ❗ 4. What &lt;em&gt;Not&lt;/em&gt; To Do
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ Do NOT use omnifunc with COQ
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;autocmd &lt;span class="nb"&gt;FileType&lt;/span&gt; markdown &lt;span class="k"&gt;setlocal&lt;/span&gt; &lt;span class="nb"&gt;omnifunc&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;coq#&lt;span class="nb"&gt;complete&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove this. COQ does not use omnifunc.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 5. Verification Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✔ Check if LSPs are connected:
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:LspInfo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  ✔ Check COQ status:
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:COQnow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  ✔ Test autocomplete
&lt;/h3&gt;

&lt;p&gt;Open a file and type --- completion should appear.&lt;/p&gt;
&lt;h2&gt;
  
  
  🐛 6. Common Issues &amp;amp; Fixes
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ❗ Autocomplete doesn't show up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  COQ not started → &lt;code&gt;:COQnow&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  LSP not attached → &lt;code&gt;:LspInfo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Missing capabilities → use &lt;code&gt;coq.lsp_ensure_capabilities()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Remove delayed init like &lt;code&gt;vim.defer_fn&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ❗ Markdown has no completion
&lt;/h3&gt;

&lt;p&gt;Install a Markdown LSP:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;ensure_installed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"marksman"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  🎉 Done!
&lt;/h1&gt;

&lt;p&gt;You now have a clean Neovim setup using &lt;strong&gt;COQ + Mason + LSP&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>neovim</category>
      <category>tooling</category>
      <category>cli</category>
      <category>coolthing</category>
    </item>
    <item>
      <title>Level Up Your Terminal Workflow: Helix + Yazi</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Tue, 04 Nov 2025 14:35:00 +0000</pubDate>
      <link>https://forem.com/albz/level-up-your-terminal-workflow-helix-yazi-1e4</link>
      <guid>https://forem.com/albz/level-up-your-terminal-workflow-helix-yazi-1e4</guid>
      <description>&lt;p&gt;If you're looking for a modern, efficient terminal-based development setup, let me introduce you to a powerful combination: &lt;strong&gt;Helix&lt;/strong&gt; (a post-modern text editor) and &lt;strong&gt;Yazi&lt;/strong&gt; (a blazingly fast terminal file manager).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Combo?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Helix&lt;/strong&gt; is a Kakoune-inspired editor with built-in LSP support, multiple cursors, and tree-sitter integration. It's fast, has sane defaults, and no plugin configuration needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yazi&lt;/strong&gt; is a terminal file manager written in Rust that's incredibly fast and intuitive. Think of it as a visual way to navigate your projects before diving into code.&lt;/p&gt;

&lt;p&gt;Together, they create a lightweight alternative to heavy IDEs while keeping you productive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving Away from JetBrains
&lt;/h2&gt;

&lt;p&gt;I've been reflecting on my development tools lately, and I'm not particularly proud of relying on JetBrains products anymore. Their direction seems increasingly Microsoft-addicted - just look at Rider becoming primarily a .NET IDE focused on game development, while languages like Erlang and other niche but important ecosystems are left out of the scene. &lt;/p&gt;

&lt;p&gt;The bloat, the subscription model, and the narrowing focus pushed me to explore lighter, more universal alternatives. That's how I discovered this setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Both Tools
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;helix yazi

&lt;span class="c"&gt;# Linux (check your distro's package manager)&lt;/span&gt;
&lt;span class="c"&gt;# Arch&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; helix yazi

&lt;span class="c"&gt;# Other distros - check helix-editor.com and yazi-rs.github.io&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configure Yazi to Open Files in Helix
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;~/.config/yazi/yazi.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[opener]&lt;/span&gt;
&lt;span class="py"&gt;edit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="py"&gt;run&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'hx "$@"'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;block&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Customize Your Helix Theme (Optional)
&lt;/h3&gt;

&lt;p&gt;Create a custom dark theme at &lt;code&gt;~/.config/helix/themes/my-theme.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;"ui.background"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;bg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#1e1e1e"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"ui.text"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#d4d4d4"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"ui.selection"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;bg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#264f78"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"ui.cursor"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#1e1e1e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;bg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#aeafad"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"ui.linenr"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#858585"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"ui.linenr.selected"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#c6c6c6"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="py"&gt;"comment"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#6a9955"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;modifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"italic"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"keyword"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#569cd6"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"function"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#dcdcaa"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"string"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#ce9178"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"variable"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#9cdcfe"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;"type"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;fg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#4ec9b0"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set it in &lt;code&gt;~/.config/helix/config.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"my-theme"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigate with Yazi:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cd&lt;/span&gt; ~/your-project
   yazi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Browse your project structure&lt;/strong&gt; using arrow keys or &lt;code&gt;hjkl&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Press Enter&lt;/strong&gt; on any file to open it in Helix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Edit in Helix&lt;/strong&gt; with LSP support, syntax highlighting, and multiple cursors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Save and exit&lt;/strong&gt; (&lt;code&gt;Ctrl+s&lt;/code&gt;, then &lt;code&gt;:q&lt;/code&gt;) to return to Yazi&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repeat&lt;/strong&gt; - navigate to next file&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Helix Quick Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Space + f&lt;/code&gt; - Fuzzy file finder&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Space + b&lt;/code&gt; - Buffer (open files) picker
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Space + /&lt;/code&gt; - Global search in project&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mf&lt;/code&gt; - Select function, &lt;code&gt;md&lt;/code&gt; - select around&lt;/li&gt;
&lt;li&gt;Multiple cursors: &lt;code&gt;C&lt;/code&gt; to add cursor, &lt;code&gt;Alt+C&lt;/code&gt; to remove&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Not Just Use Helix's Built-in Picker?
&lt;/h2&gt;

&lt;p&gt;You absolutely can! Helix has excellent fuzzy finding (&lt;code&gt;Space + f&lt;/code&gt;). But Yazi gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual tree structure&lt;/li&gt;
&lt;li&gt;Quick file operations (copy, move, rename)&lt;/li&gt;
&lt;li&gt;Image previews&lt;/li&gt;
&lt;li&gt;Directory sizes&lt;/li&gt;
&lt;li&gt;A complementary tool for different tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This setup gives you the speed and simplicity of terminal tools with the power of modern editing features. No Electron bloat, no complex plugin configurations - just fast, efficient coding.&lt;/p&gt;

&lt;p&gt;Give it a try and let me know what you think!&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://helix-editor.com" rel="noopener noreferrer"&gt;Helix Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://yazi-rs.github.io" rel="noopener noreferrer"&gt;Yazi File Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.helix-editor.com/themes.html" rel="noopener noreferrer"&gt;Helix Themes Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>helix</category>
      <category>terminal</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Introducing RSS Reader: A Modern Native RSS Client for macOS</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Mon, 08 Sep 2025 12:54:11 +0000</pubDate>
      <link>https://forem.com/albz/introducing-rss-reader-a-modern-native-rss-client-for-macos-3lna</link>
      <guid>https://forem.com/albz/introducing-rss-reader-a-modern-native-rss-client-for-macos-3lna</guid>
      <description>&lt;p&gt;I'm excited to share my latest creation: &lt;strong&gt;RSS Reader&lt;/strong&gt;, a sleek and modern RSS client built specifically for macOS using Swift. This application brings back the joy of RSS feeds with a fluid, optimized user experience designed specifically for the Apple ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It Special
&lt;/h2&gt;

&lt;p&gt;RSS Reader is built from the ground up as a native macOS application, ensuring smooth performance and seamless integration with your Mac. The app features a clean, intuitive interface that makes managing and reading your favorite RSS feeds effortless.&lt;/p&gt;

&lt;p&gt;Key highlights include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native Swift Development&lt;/strong&gt;: Built specifically for macOS, ensuring optimal performance and system integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Architecture&lt;/strong&gt;: Clean, maintainable code with proper separation of concerns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-Friendly Interface&lt;/strong&gt;: Intuitive design that focuses on readability and ease of use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Parsing&lt;/strong&gt;: Robust RSS parsing with proper error handling and data persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;p&gt;The application uses a sophisticated parsing system with XMLParser and delegate patterns, ensuring reliable feed processing. It includes proper data persistence through ModelContext and supports both individual feed updates and bulk refresh operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Download&lt;/strong&gt;: &lt;a href="https://github.com/AlbertoBarrago/RSS-Reader" rel="noopener noreferrer"&gt;RSS Reader on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository includes complete build instructions - simply clone, open in Xcode, and run. Whether you're using the simulator or a physical device, getting started is straightforward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community Discussion&lt;/strong&gt;: Join the conversation about RSS Reader on &lt;a href="https://www.reddit.com/r/MacOS/comments/1n98vr6/rssfeeder/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt; where I've shared more details about the development process and gathered feedback from the macOS community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building and Running
&lt;/h2&gt;

&lt;p&gt;Requirements are minimal - just macOS with Xcode installed. The project includes detailed setup instructions and a comprehensive RUN.md file to get you started quickly.&lt;/p&gt;

&lt;p&gt;RSS Reader represents my commitment to creating quality, native applications for the Apple ecosystem. Give it a try and rediscover the power of RSS feeds with a modern, polished interface.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Swift for macOS | Open Source | Community Driven&lt;/em&gt;&lt;/p&gt;

</description>
      <category>swift</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Chrome Cookbook: Recipes for a Better Workflow</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Thu, 28 Aug 2025 07:39:29 +0000</pubDate>
      <link>https://forem.com/albz/the-chrome-cookbook-recipes-for-a-better-workflow-56f2</link>
      <guid>https://forem.com/albz/the-chrome-cookbook-recipes-for-a-better-workflow-56f2</guid>
      <description>&lt;p&gt;Want to become a Chrome power user? Skip the long-winded articles. This is a cookbook of simple, effective "recipes" to make your browsing and development more efficient. Just a few lines per tip—copy, paste, and master.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The Search Chef's Pantry&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your address bar is a powerful kitchen tool. Learn these basic ingredients to cook up the perfect search query every time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exact Phrase:&lt;/em&gt; To find the exact phrase, wrap it in quotes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"devops engineer salary"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exclusion:&lt;/em&gt; To remove a keyword, use a minus sign.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jaguar -car (finds the animal)&lt;/code&gt; or &lt;code&gt;hello -ai (without ai preview)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Site-Specific Search:&lt;/em&gt; To search only one website, use site:.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;site:dev.to "containerization"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;File Type Search:&lt;/em&gt; To find a specific file type, use filetype:.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;react native cheatsheet filetype:pdf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Date Range:&lt;/em&gt; To find results within a specific time frame, use before: or after:.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AI research after:2024-01-01&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Title Search:&lt;/em&gt; To find a keyword only in the page title, use intitle:.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;intitle:"Fullstack developer" roadmap&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Final Dish&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These recipes are just a starting point. Mix and match them to create your own unique workflow. As a fellow developer, I find these tips help me save precious minutes from my daily tasks.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The New Era of Color on the Web: Understanding OKLCH</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Mon, 25 Aug 2025 13:29:27 +0000</pubDate>
      <link>https://forem.com/albz/the-new-era-of-color-on-the-web-understanding-oklch-dnp</link>
      <guid>https://forem.com/albz/the-new-era-of-color-on-the-web-understanding-oklch-dnp</guid>
      <description>&lt;p&gt;The way we define and use color on the web is evolving. While older models like sRGB have been the standard, a new, more intuitive system is gaining traction: OKLCH. This article will explore what OKLCH is, its benefits, and how you can start using it today.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What is OKLCH?&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;OKLCH is a modern color model that is perceptually uniform&lt;/strong&gt;. This means it's designed to align more accurately with how the human eye perceives color. Unlike sRGB, which can behave unpredictably, OKLCH gives you a more reliable way to work with colors. It's composed of three key values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L (Lightness): How light or dark a color is.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C (Chroma): The intensity or vividness of a color.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;H (Hue): The shade of the color (e.g., red, blue, green).&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This structure makes it incredibly simple to create harmonious color palettes and gradients. For example, by keeping the "L" and "C" values consistent, you can generate a series of shades that maintain the same perceived brightness, avoiding the "hue drift" that can happen with other models.&lt;/p&gt;

&lt;p&gt;The Impact on Visualization and Compatibility&lt;br&gt;
The move to OKLCH is part of a larger shift in the web's visualization era, where modern displays support a wider range of colors, or "gamut," than the traditional sRGB standard. OKLCH can access these wider color spaces, allowing designers to create more vibrant and vivid designs.&lt;/p&gt;

&lt;p&gt;A crucial aspect of this transition is ensuring compatibility. While most modern browsers support OKLCH, older browsers do not. This is where CSS's @supports rule comes in. It allows you to provide a fallback for older browsers, ensuring your design looks good everywhere.&lt;/p&gt;

&lt;p&gt;Here is an example of how to implement this using a simple gray color palette, as you requested:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* sRGB hex */&lt;/span&gt;
    &lt;span class="py"&gt;--color-gray-100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fcfcfc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--color-gray-200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fafafa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--color-gray-300&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f4f4f4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="err"&gt;@supports&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
      &lt;span class="c"&gt;/* OKLCH */&lt;/span&gt;
      &lt;span class="n"&gt;--color-gray-100&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.991&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="py"&gt;--color-gray-200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.982&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="py"&gt;--color-gray-300&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;oklch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.955&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&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="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code snippet first defines the gray colors using the standard sRGB hex codes. Then, within the @supports block, it redefines those colors using the OKLCH values. Browsers that understand oklch will use the new values, while older ones will fall back to the hex codes, ensuring a consistent user experience.&lt;/p&gt;

&lt;p&gt;You can learn more about this topic and see a practical tool for generating color palettes at the original source: &lt;a href="https://jakub.kr/components/oklch-colors" rel="noopener noreferrer"&gt;jakub.kr&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>oklch</category>
      <category>programming</category>
    </item>
    <item>
      <title>Proctoring – My Latest Side Project to Catch Cheaters (Gently)</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Tue, 22 Jul 2025 14:26:45 +0000</pubDate>
      <link>https://forem.com/albz/proctoring-my-latest-side-project-to-catch-cheaters-gently-4b55</link>
      <guid>https://forem.com/albz/proctoring-my-latest-side-project-to-catch-cheaters-gently-4b55</guid>
      <description>&lt;p&gt;Hey everyone!&lt;br&gt;
I just published &lt;a href="https://github.com/AlbertoBarrago/proctoring" rel="noopener noreferrer"&gt;Proctoring&lt;/a&gt;, a side project I’ve been working on in my free time. It's a lightweight browser-based proctoring system built with PHP and JavaScript.&lt;/p&gt;

&lt;p&gt;The goal? Help detect suspicious behavior during online exams—without needing a big AI team or a million-dollar budget.&lt;/p&gt;

&lt;p&gt;It can track things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the student is looking away from the screen too much&lt;/li&gt;
&lt;li&gt;If another person appears on camera&lt;/li&gt;
&lt;li&gt;If a phone is in view&lt;/li&gt;
&lt;li&gt;If there are unexpected sounds or voices in the background&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not perfect (yet), but it’s a start—and it was a great excuse to dive deeper into browser media APIs, video analysis, and some clever tricks to sync everything in real-time.&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>ai</category>
      <category>proctoring</category>
    </item>
    <item>
      <title>Doc-Piloot: Because Bad READMEs Are a Crime Against Humanity</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Fri, 04 Jul 2025 13:56:58 +0000</pubDate>
      <link>https://forem.com/albz/doc-piloot-because-bad-readmes-are-a-crime-against-humanity-1ho5</link>
      <guid>https://forem.com/albz/doc-piloot-because-bad-readmes-are-a-crime-against-humanity-1ho5</guid>
      <description>&lt;p&gt;&lt;em&gt;Or: How I Got Tired of Seeing "TODO: Add README" on Every Repo&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem That Broke My Soul
&lt;/h2&gt;

&lt;p&gt;Picture this: You're browsing GitHub, you find what looks like an amazing project, you click on the repo and... BAM. Either there's no README at all, or worse, there's a README that just says "My awesome project" with zero context about what it actually does.&lt;/p&gt;

&lt;p&gt;After years of encountering these digital wastelands disguised as documentation, I finally snapped. I couldn't take it anymore. The developer in me screamed "THERE HAS TO BE A BETTER WAY!"&lt;/p&gt;

&lt;p&gt;So I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet Doc-Piloot (Yeah, the Name's a Story)
&lt;/h2&gt;

&lt;p&gt;I wanted to call it "Doc-Pilot" because, you know, it's like having a copilot for your documentation. Makes sense, right? Wrong. Turns out that name was already taken. So here we are with "Doc-Piloot" which honestly sounds even cooler because it's got that mysterious European flair.&lt;/p&gt;

&lt;p&gt;Doc-Piloot is your AI copilot for project documentation that automatically generates comprehensive README files for GitHub repositories. It's like having a technical writer on your team who never sleeps, never complains, and actually understands your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How This Magic Works
&lt;/h2&gt;

&lt;p&gt;The beauty of Doc-Piloot is in its simplicity. You literally just:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the GitHub App&lt;/strong&gt; on your repository&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add &lt;code&gt;--doc&lt;/code&gt; to your commit message&lt;/strong&gt; when you push to main&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Watch the magic happen&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No complex configuration, no lengthy setup processes, no sacrificing your firstborn to the documentation gods.&lt;/p&gt;

&lt;p&gt;When you push a commit with &lt;code&gt;--doc&lt;/code&gt; in the message, Doc-Piloot springs into action:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It analyzes your entire repository structure&lt;/li&gt;
&lt;li&gt;Detects programming languages and frameworks&lt;/li&gt;
&lt;li&gt;Understands your project's purpose and functionality&lt;/li&gt;
&lt;li&gt;Generates a professional README.md file&lt;/li&gt;
&lt;li&gt;Creates a pull request on a new branch called &lt;code&gt;update-readme&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the &lt;code&gt;update-readme&lt;/code&gt; branch doesn't exist, it creates one. If it does exist, it updates it. It's like having a very organized, very efficient documentation assistant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack (For the Nerds)
&lt;/h2&gt;

&lt;p&gt;Doc-Piloot is built with some seriously cool technology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; Bleah... just for audience&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Gemini AI&lt;/strong&gt; for the brain power&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub API&lt;/strong&gt; via Octokit for seamless integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart analysis algorithms&lt;/strong&gt; that actually understand your code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The AI doesn't just generate generic fluff. It actually looks at your code, understands the structure, identifies the main technologies you're using, and creates documentation that makes sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters More Than You Think
&lt;/h2&gt;

&lt;p&gt;Good documentation isn't just about being nice to other developers (though that's important too). It's about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reducing onboarding time&lt;/strong&gt; for new team members&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Making your projects more discoverable&lt;/strong&gt; and trustworthy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saving your future self&lt;/strong&gt; from the "what does this code do?" confusion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actually shipping projects&lt;/strong&gt; instead of procrastinating on documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've seen too many brilliant projects die in obscurity because nobody could figure out how to use them. Don't let your code become digital archaeology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Out (Seriously, Do It)
&lt;/h2&gt;

&lt;p&gt;If you're tired of staring at empty README files, or if you're one of those people who's been putting off writing documentation for months, give Doc-Piloot a shot.&lt;/p&gt;

&lt;p&gt;The worst that can happen is you get a professionally written README for free. The best that can happen is you never have to write another README from scratch again.&lt;/p&gt;

&lt;p&gt;Because life's too short for bad documentation, and your projects deserve better than "TODO: Add README."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/AlbertoBarrago/doc-piloot" rel="noopener noreferrer"&gt;Repo&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your biggest documentation pain point? Have you tried any other automated documentation tools? Let me know in the comments - I'm always looking for ways to make Doc-Piloot even better.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; If you're wondering why I'm so passionate about this, it's because I've spent way too many hours trying to figure out how to use undocumented projects. Consider this my gift to future developers who just want to understand what your code does without having to reverse engineer it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>javascript</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>The Mirror We Built</title>
      <dc:creator>Alberto Barrago</dc:creator>
      <pubDate>Wed, 18 Jun 2025 23:12:00 +0000</pubDate>
      <link>https://forem.com/albz/the-mirror-we-built-1aph</link>
      <guid>https://forem.com/albz/the-mirror-we-built-1aph</guid>
      <description>&lt;p&gt;Let me be clear: intelligence is not in the machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMHO&lt;/strong&gt;, what we’re seeing today is just a reflection of us. Of our choices, our questions, our awareness, or sometimes, our laziness.&lt;/p&gt;

&lt;p&gt;We used to ask each other things in bars. Then we trusted the television. Now many ask search boxes or chat interfaces questions like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can I find love?&lt;br&gt;&lt;br&gt;
Can you make me a startup with a button that prints money?&lt;br&gt;&lt;br&gt;
Should I invest in crypto now?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you don’t know what you’re really asking, and you expect a shortcut to something you don’t understand, who’s responsible?&lt;/p&gt;

&lt;p&gt;The machine??&lt;/p&gt;

&lt;p&gt;Or the person using it?&lt;/p&gt;




&lt;h2&gt;
  
  
  Tools Don't Make You Smarter
&lt;/h2&gt;

&lt;p&gt;The tool is innocent.&lt;/p&gt;

&lt;p&gt;Fire is a tool. So is money. So is code.&lt;/p&gt;

&lt;p&gt;And so is this thing everyone keeps calling “intelligent.”&lt;/p&gt;

&lt;p&gt;But power doesn’t mean wisdom. If you can’t handle the tool, if you use it like a crutch or a trick, it won’t elevate you. It’ll just &lt;em&gt;expose you&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What you get depends on what you give.&lt;/p&gt;




&lt;h2&gt;
  
  
  Raise Your Standards
&lt;/h2&gt;

&lt;p&gt;If you ask something without thought, you’ll get something empty. If you don’t reflect, don’t study, don’t go deep... don’t expect magic.&lt;/p&gt;

&lt;p&gt;This isn’t about jobs or automation. &lt;em&gt;The real danger isn’t being replaced.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It’s forgetting how to think.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A Question Worth Asking
&lt;/h2&gt;

&lt;p&gt;What do you want from the tools you use?&lt;/p&gt;

&lt;p&gt;Are you building? Reflecting? Creating something real?&lt;/p&gt;

&lt;p&gt;Let’s talk about it. The tool is in our hands. What we do with it, that’s the only part that matters.&lt;/p&gt;

&lt;p&gt;Drop your thoughts. Let’s keep this human ♥️&lt;/p&gt;

</description>
      <category>developer</category>
      <category>programming</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
