<?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: Anna Villarreal</title>
    <description>The latest articles on DEV Community by Anna Villarreal (@annavi11arrea1).</description>
    <link>https://dev.to/annavi11arrea1</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%2F1467610%2F6ede9a19-775f-483a-b3b8-2bb47e8f954b.jpg</url>
      <title>DEV Community: Anna Villarreal</title>
      <link>https://dev.to/annavi11arrea1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/annavi11arrea1"/>
    <language>en</language>
    <item>
      <title>🐈‍⬛Check Out Catbot's New Leg!</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sat, 25 Jul 2026 01:40:56 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/check-out-catbots-new-leg-3cfg</link>
      <guid>https://dev.to/annavi11arrea1/check-out-catbots-new-leg-3cfg</guid>
      <description>&lt;p&gt;This is fun. I absolutely must share.&lt;/p&gt;

&lt;p&gt;So I recently created a desktop pet, called Catbot. Catbot is voice activated and has memory in an obsidian vault that it shares with models of choice as needed. Catbot is a harness that feels like a pet. I quickly built Catbot a body using AI and was excited to see the result was a furry creature with a robotic leg, which I had asked for. This worked for messing around and building Catbot to start. Here are some images I generated with ai in a previous week, just to catch you up to speed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxfgg3tro3w0tpe4s6c4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxfgg3tro3w0tpe4s6c4.png" alt="awkward rendering, but pretty on point" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;
Awkward initial rendering needing refinement



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5uazzg5v337off5q0fi8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5uazzg5v337off5q0fi8.png" alt="high level technical drawing" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;
A high level mock technical drawing generated by Gemini I used to generate Catbot's original body



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp525lgzgaudl2ol5135y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp525lgzgaudl2ol5135y.png" alt="Catbot's first 3D body" width="452" height="488"&gt;&lt;/a&gt;&lt;/p&gt;
Original Catbot appearance.







&lt;p&gt;But that badly represented robotic pet leg was getting on my nerves. I knew it had to be better. In the back of my head I was like you know what, it needs a way better leg. I let it fester in my head for a while. Then finally, I couldn’t take it anymore. The next moment of free time I sat down and drew up what I thought a robotic pet leg might look like. I drew this quickly, in about 15 minutes or so. I was happy with the overall idea, and believed it made sense. Here is my drawing:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkysw0u5inpvdjqsmmyt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkysw0u5inpvdjqsmmyt.jpg" alt="Catbot leg idea" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;
My original drawing







&lt;p&gt;After creating the drawing, I knew that I had to have multiple views to have enough data for ai to create a working prototype. I gave my drawing to Gemini using the following prompt:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“I created this robotic cat leg and I need some good technical drawings of top, side view, front view and back. Can you make me a good technical drawing I can use to share my idea? “&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And having luck previously with a different type of schematic (the original Catbot) I knew that this would at least produce something marginally workable. I was absolutely blown away by the mock schematic it produced for me. It is freaking beautiful, exactly what I wanted!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc09c7kayl99aj6x9uqc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc09c7kayl99aj6x9uqc8.png" alt="Really awesome robotic leg schematic for Catbot" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;
Nice looking technical drawing by Gemini.







&lt;p&gt;I then gave the schematic with a detailed description to opus for creation using existing Catbot architecture, (using three.js) to create the fantastic leg for me. It did a pretty good job!&lt;/p&gt;

&lt;p&gt;I’ve added a video so you can see an interaction with Catbot. It’s entertaining until it frustrates you. Work in progress for sure. LOL. It was difficult to get Catbot's opintion of it's new leg:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/nc5-3uJkZAY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Catbot is a brat. Do not give your AI pet sass. (You know, unless you can deal with it.) 😂&lt;/p&gt;

&lt;p&gt;And let's not forget where we started:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4i50qlej8sa9spi8cfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4i50qlej8sa9spi8cfe.png" alt="Catbot the first" width="279" height="215"&gt;&lt;/a&gt;&lt;/p&gt;
Catbot the first.



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffv2vli5prckqjohi025j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffv2vli5prckqjohi025j.png" alt="Catbot the second" width="438" height="411"&gt;&lt;/a&gt;&lt;/p&gt;
Catbot the second.



&lt;p&gt;So I guess this latest Catbot, is Catbot the 4th. &lt;/p&gt;

&lt;p&gt;Has anyone else created an AI pet?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>learning</category>
      <category>pet</category>
    </item>
    <item>
      <title>FLUX on a 4070 Graphics Card 🖼️</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sat, 18 Jul 2026 14:32:08 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/flux-on-a-4070-graphics-card-297</link>
      <guid>https://dev.to/annavi11arrea1/flux-on-a-4070-graphics-card-297</guid>
      <description>&lt;h2&gt;
  
  
  Preliminary
&lt;/h2&gt;

&lt;p&gt;In the past, I have tried a few things to get local video and image generation to work to my satisfaction. I was irritated for a while that my older macbook didn’t have an M chip because I know you can do some cool stuff with Ollama. But I am not buying a computer every year. That’s unrealistic and wasteful. One of my recent stunts involved trying to get fable to setup a workflow on comfyUI. While that’s novel and impressive-looking, the output was poor at best and I was not amused. Node confusion, half of them in languages I cannot read. I already have too many projects, I’m not about to decipher foreign languages on the fly or watch 30 node handling videos on Youtube over the course of 3 months. Time is a real factor here.&lt;/p&gt;

&lt;p&gt;With the 3rd extension of free fable use I’m squeezing every last drop out of it. I’m not wasting it either - I’ve got it dropping all kinds of notes to my vault so I can reproduce things on my own later. And honestly, that’s serious real world value for my workflow.&lt;/p&gt;

&lt;p&gt;Before I ramble, I must give credit to Youtuber Richard Aragon for sharing his magnificent google colab notebook. I stumbled into this whole process on accident looking for videos about quantization in an effort to know more about what the eff is quantization really. Little did I know this attempted deep dive would lead me down a path to resolve a personal problem of local generation. By the way, he mentions being able to do this on a 4060, so guys, all is not lost if you have a little bit of patience and good timing. I have come to find out that as developers we have unparalleled patience. So then, this post is for you. If I can save a single person from massive frustration, then I have done my job. It is better to share than to hoard. Because, like Richard Aragon, I would much prefer to share and help. &amp;lt;3&lt;/p&gt;





&lt;h2&gt;
  
  
  Start Your Own Workflow
&lt;/h2&gt;

&lt;p&gt;Here is Richard’s Youtube link and the google colab is in the notes: &lt;a href="https://www.youtube.com/watch?v=gjkVW3qOUMA%22" rel="noopener noreferrer"&gt;AI Quantization Easily Explained&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is really amazing is that I discovered I can use a quantized model locally and train it on my own content. As an artist, I was extremely curious to see how AI might create images for me in my art style. Mission accepted!&lt;/p&gt;

&lt;h3&gt;
  
  
  Here is EXACTLY what I did with no shame:
&lt;/h3&gt;

&lt;p&gt;❤️ I gave Fable the link to the google colab notebook, explaining what I was trying to accomplish. Fable fetched the data from the notebook and created it locally - a private copy of the workflow for me to modify as I wish.&lt;br&gt;
🧡 Using the 34GB  base model from Hugging Face, I am now able to train it on my own images to create my own style. This is accomplished by using a LoRA file which acts as a “lense” that attaches to the base model. This means that you can train it to have many lens (styles!) on your local workflow.  In his video, Richard uses pieces from the late Alphonse Mucha (Famous artist if you haven’t heard) to train the model. The results were on point, and even after quantization they still held enough data to hold onto most defining characteristics.  Using this knowledge, I ran the same tests as him for a control.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One test without training.&lt;/li&gt;
&lt;li&gt;One test with training.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💛 After testing, I knew the structure was in place for experimentation. The first thing I needed to do was to create a folder with my artwork, 14 images, and a metadata.jsonl file. (made my first jsonl file from scratch yesterday, cool haha). This metadata pairs the description of the image to the actual image so FLUX can interpret it for training.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demystification
&lt;/h2&gt;

&lt;p&gt;Here is essentially how we get a 12GB card to handle a 24 GB model. I’ve simplified the terminology for learning and demystification purposes:&lt;/p&gt;

&lt;p&gt;💚 &lt;strong&gt;Shrink/Quantization&lt;/strong&gt; Specifically 4-bit NF4 quantization (NormalFloat4), done by the bitsandbytes library. "8-bit" and "4-bit" refer to how many bits store each model weight.            &lt;/p&gt;

&lt;p&gt;🩵 &lt;strong&gt;Freeze/Parameter-efficient fine-tuning&lt;/strong&gt; (PEFT), specifically LoRA (Low-Rank Adaptation). The base model's parameters are frozen, so you train small low-rank adapter matrices instead.  &lt;/p&gt;

&lt;p&gt;💜 &lt;strong&gt;Precompute/Embedding&lt;/strong&gt; caching and and latent caching.                                                                                                &lt;/p&gt;

&lt;p&gt;🩷 &lt;strong&gt;Right-size/No single fancy word&lt;/strong&gt; Memory footprint management: lower training resolution, batch size 1 with gradient accumulation, gradient checkpointing (recompute instead of store), and an 8-bit optimizer. Each trades a little speed or precision for a lot of memory.  &lt;/p&gt;

&lt;p&gt;No fancy UI at the moment (...already have plan for that 😂) but using the terminal and running the python script afterwards with optional parameters offers additional flexibility of image generation. &lt;/p&gt;




&lt;h2&gt;
  
  
  Here are the generations from my first local tests
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Control 1 - untrained
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzci6u1cp86zw5z50k9di.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzci6u1cp86zw5z50k9di.png" alt="untrained local" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Control 2 - Alphonse Mucha
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkea1ajslb3fvlzgtcctd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkea1ajslb3fvlzgtcctd.png" alt="trained control" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Training 1 - 100 step artwork (fast, minutes)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1pzdvu3mhntdgidwug6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1pzdvu3mhntdgidwug6z.png" alt="14 pieces of art" width="493" height="534"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Test 1 - 100 step artwork (EVERFLUO style)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdrlf3ivariie4mwvi4fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdrlf3ivariie4mwvi4fb.png" alt="custom baseline" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Training 2 - 700 step artwork (over an hour)
&lt;/h3&gt;
&lt;h3&gt;
  
  
  Test 2 - 700 step artwork (EVERFLUO style)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwp9593i2x4i7tvewt596.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwp9593i2x4i7tvewt596.png" alt="refined model style" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
Much closer resemblance to style.






&lt;h3&gt;
  
  
  Test 3 - Ran EVERFLUO style with very custom prompt to see limitations, needs work/additional training to be extra fancy.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdwe8knlap1ewwuifjv1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdwe8knlap1ewwuifjv1i.png" alt="Pushing model outside of training" width="799" height="520"&gt;&lt;/a&gt;&lt;br&gt;
Pushing model outside of training to see what happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  What about video?
&lt;/h2&gt;

&lt;p&gt;I was able to piggy-back off of the pre-existing image generation setup to build a video generation workflow. I am currently taking a stab at a 5 second video on the 4070 on one of my paintings. It's going to be at least an hour and I will update this post.&lt;/p&gt;

&lt;p&gt;Here is the first video!&lt;/p&gt;


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






&lt;p&gt;On that note, I'll survive another year without a 5090, maybe XD.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>image</category>
      <category>video</category>
      <category>local</category>
    </item>
    <item>
      <title>Bitarazzi Short Film: Imperfect Awesomeness🌱</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Thu, 16 Jul 2026 01:07:02 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/bitarazzi-short-film-imperfect-awesomeness-5ceb</link>
      <guid>https://dev.to/annavi11arrea1/bitarazzi-short-film-imperfect-awesomeness-5ceb</guid>
      <description>&lt;p&gt;I want to give you spoilers but you must watch it first. Here's basically what happened. &lt;/p&gt;

&lt;p&gt;Firstly, this project was for fun.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The lyrics where generated by Claude first with a prompt including what we were after. &lt;/li&gt;
&lt;li&gt;The music was generated by Suno after telling it we wanted something that sounded like "Paparazzi" by Lady Gaga, shortly after coining the term "bitarazzi"&lt;/li&gt;
&lt;li&gt;The videos and images were generated by Gemini and I ended up developing a character, or two.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found myself creating a story with meaning in the video, that related to my own life as I pieced it together in 10 second spurts (3 ten second videos per day on Gemini free tier, don't mess up or you have to wait!)&lt;/p&gt;

&lt;p&gt;AI is not all evil or bad. To me, I see it as a creative outlet. It's fun. Sure (Spoiler alert!!!!!) she might be plugging the ethernet cord in upside down, but the idea is generally communicated in a decent way.&lt;/p&gt;

&lt;p&gt;I completed this in the mornings as I had time over the course of a few weeks. I could refine it forever, but I think it's cool how fast you can buzz along with a creative project/prototype/idea with AI. So cool. They didn't have this when I was a teenager!&lt;/p&gt;

&lt;p&gt;I did actual human editing in adobe premier to string it together in a way that semi made sense! Hope you like the bitarazzi debut, haha!&lt;/p&gt;

&lt;p&gt;Thank you &lt;a class="mentioned-user" href="https://dev.to/trickell"&gt;@trickell&lt;/a&gt; for your help and inspiration! &amp;lt;3&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gemini</category>
      <category>claude</category>
    </item>
    <item>
      <title>🐈Catbot: The Custom AI Harness That Lives on Desktop ᓚᘏᗢ</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Mon, 13 Jul 2026 04:55:27 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/catbot-the-custom-ai-harness-that-lives-on-desktop-layottu-35kb</link>
      <guid>https://dev.to/annavi11arrea1/catbot-the-custom-ai-harness-that-lives-on-desktop-layottu-35kb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;This weekend, I went on a journey to build a voice activated assistant on my desktop, named Catbot. In the process, I switched from notion over to obsidian. Obsidian acts as a knowledge base for the agents to communicate. Catbot is a custom harness I built that I can use with any of my agents. Catbot is voice activated and sleeps in a bed when I tell him too. I also created a small skin modifier to change it's appearance.&lt;/p&gt;





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

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/zv6Clx7aemk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;
Catbot switches voices in real time on my desktop!







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

&lt;p&gt;Here is a snippet from my catbot_voice.py. This is a private project at the moment, but I am comfortable sharing the initial setup with everyone!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sounddevice&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;vosk&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;kokoro_onnx&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Kokoro&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.env&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;catbot.voice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ROOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;
&lt;span class="n"&gt;KOKORO_ONNX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ROOT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kokoro-v1.0.onnx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;KOKORO_VOICES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ROOT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;voices-v1.0.bin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;VOSK_BIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ROOT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vosk-model-en-us-0.22-lgraph&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;VOSK_SMALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ROOT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;vosk-model-small-en-us-0.15&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;SAMPLE_RATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16000&lt;/span&gt;
&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://localhost:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;CATBOT_PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;8800&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Tolerant of how recognizers mangle "catbot": fuzzing Vosk against Kokoro
# speech produced "cat bought", "that bought", "cat ba bought", "can't bought",
# "cat bottom gauge"... A false wake just means he listens, so err generous.
&lt;/span&gt;&lt;span class="n"&gt;BOT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:cat|kat|cad|catt|that|can&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?t|cap)\s*-?\s*(?:\w{1,3}\s+)?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
       &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:bottom|bought|boat|both|body|bert|bird|bot|but)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# every way of telling him to be quiet actually works now — "shut down",
# "stop", "quiet" etc. used to fall through to the LLM, which would *claim*
# to shut down while nothing happened
&lt;/span&gt;&lt;span class="n"&gt;STOP_WORDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:go\s+to\s+)?(?:sleep|slee|asleep)|shut\s*(?:down|up)|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
              &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?:be\s+)?quiet|stop(?:\s+(?:listening|talking))?|&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
              &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;power\s+(?:down|off)|turn\s+off|pause|hush|silence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RE_SLEEP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BOT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[,!.\s]*(?:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;STOP_WORDS&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RE_ENGAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BOT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[,!.\s]*(?:(?:en\s*)?(?:engage|gage|gauge|engaged|gaged)d?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                             &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|wake\s*up|wake)[,!.\s]*(.*)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# While ASLEEP, bias hard toward waking: a missed wake makes him unusable,
# a false wake just means he listens. Any engage-ish or wake-ish word wakes.
&lt;/span&gt;&lt;span class="n"&gt;RE_WAKE_LOOSE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\b(?:en|in|and|un)?[\s-]*(?:gage|gauge|engage)[ds]?\b|\bwake+\s*(?:up|it)?\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# in-conversation commands
&lt;/span&gt;&lt;span class="n"&gt;PROVIDER_WORDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;google&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chatgpt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chat gpt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open ai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openai&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;local&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qwen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&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;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A FastAPI &lt;strong&gt;server&lt;/strong&gt; server.py is the single brain-stem: every surface talks to Catbot over HTTPS on port 8800. &lt;/li&gt;
&lt;li&gt;Catbot routes chats to chosen &lt;strong&gt;provider&lt;/strong&gt; in providers.py, injects the shared memory from the obsidian vault.&lt;/li&gt;
&lt;li&gt;runs background agent missions, and turns &lt;code&gt;catbot-publish&lt;/code&gt; blocks in replies into real files like vualt notes or web pages.&lt;/li&gt;
&lt;li&gt;Catbot is a transparent always-on-top window with its own offline voice engine catbot_voice.py: Vosk hears speech, intents route commands, Kokoro answers aloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was first using kokoro for voices and then I discovered the amazing possibilities for voices at eleven labs. I recorded enough of my voice to make a pretty close clone, and it's definitely interesting to hear yourself talk back to you.&lt;/p&gt;

&lt;p&gt;There is a web view but he mostly just lives floating on the desktop - where I want Catbot to live.&lt;/p&gt;





&lt;p&gt;I went through some modifications during this process. Catbot started out Grey and then I added a skin modifier:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9z82r4gt61vvmqxqec7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9z82r4gt61vvmqxqec7l.png" alt="Grey Catbot" width="279" height="215"&gt;&lt;/a&gt;&lt;/p&gt;
Original rendering of Catbot



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fji78s28aajf93pnck7gm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fji78s28aajf93pnck7gm.png" alt="Skin modifier" width="608" height="498"&gt;&lt;/a&gt;&lt;/p&gt;
Skin modifier for Catbot!



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr2a0pjxuztqluoof8ndk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr2a0pjxuztqluoof8ndk.png" alt="Bedtime" width="373" height="333"&gt;&lt;/a&gt;&lt;/p&gt;
Catbot goes to sleep!



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9943922jw5s06gp56uvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9943922jw5s06gp56uvu.png" alt="Web interface" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;
Catbot optional web interface



&lt;p&gt;I am obsessed with my new digital pet cat, and that's why I had to share him for this passion project. Thank you for reading!&lt;/p&gt;





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

&lt;p&gt;I am submitting for Best Use of ElevenLabs. Using a custom built voice, I was able to integrate it through the API easily to Catbot to add to my voice bank!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simple Benchmark Review: Ollama on Jetson Nano</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sun, 12 Jul 2026 05:43:01 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/simple-benchmark-review-ollama-on-jetson-nano-5gee</link>
      <guid>https://dev.to/annavi11arrea1/simple-benchmark-review-ollama-on-jetson-nano-5gee</guid>
      <description>&lt;p&gt;Previous Related Post: &lt;a href="https://dev.to/annavi11arrea1/jetson-nano-ollama-optimal-quantization-2de8"&gt;Part 1&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;This particular rabbit hole was created due to a previous conversation I had here with another member on DEV about benchmarking and tests. Lot's of questions sparked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's the best way to do them? &lt;/li&gt;
&lt;li&gt;How do we do them? &lt;/li&gt;
&lt;li&gt;What are good numbers? &lt;/li&gt;
&lt;li&gt;What information is actually important?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The truth is that it heavily depends on what you are doing and what is important to you, first and foremost. For me, and my little test generation app, my purpose seemed simple: create a simple app using ai, locally, for free, and take text I have and generate flashcards and quizzes from it so I can review. I can tell you by this point I have spent less time reviewing and more time digging into interesting tools. &lt;/p&gt;

&lt;p&gt;On this particular journey, man - I did so much I'm having trouble knowing what to explain first. But I'll try to stick to testing. So basically, I wanted to see which model would run the best on my nano, you know without crashing it, because I did do that actually at one point. That's a tangent I'll save for later but I saved by conversation with claude in my techdocs if you want some entertainment. ( &lt;a href="https://techdocs.annavillarreal.com" rel="noopener noreferrer"&gt;techdocs&lt;/a&gt; --&amp;gt; then click jetson nano on the left. ) I did not have enough ram on my nano to handle the test run. This led me to create a swap file to accommodate for lack of ram in case of emergency. Just as a safety net - since I get into trouble.&lt;/p&gt;

&lt;p&gt;Safety net in place, I create a quick quiz of the OSI model from a web page to use as source of truth - something to compare the results to. Thanks Vinicius Pereira for the ideas in our chat! So, I ran this test against each one of the models and varying 'quantizations' (is that a word yet?) to bring to light the mystery of this concept. &lt;/p&gt;

&lt;h3&gt;
  
  
  The high level - if a model is heavily quantized, you lose quality. Brass tax.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvu88h6fh4w4g1kdi0m71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvu88h6fh4w4g1kdi0m71.png" alt="benchmark tests" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I went to these great lengths and then only come to realize, sheesh, this is only for one specific use case. This would take a minute to map performance across many different use cases. I wonder, if you have nano, what have you used Ollama for on it? Not like I need another reason to hoard data. XD&lt;/p&gt;

&lt;p&gt;Anyways, in case you don't feel like navigating away, here's a table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Model&lt;/th&gt;
      &lt;th&gt;Quant&lt;/th&gt;
      &lt;th&gt;Accuracy&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
&lt;td&gt;qwen2.5:3b-instruct&lt;/td&gt;
&lt;td&gt;q4_K_M&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;qwen2.5:3b-instruct&lt;/td&gt;
&lt;td&gt;q5_K_M&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;qwen2.5:3b-instruct&lt;/td&gt;
&lt;td&gt;q8_0&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;qwen3.5:2b&lt;/td&gt;
&lt;td&gt;q4_K_M&lt;/td&gt;
&lt;td&gt;0% (empty output)&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;qwen3.5:2b&lt;/td&gt;
&lt;td&gt;q8_0&lt;/td&gt;
&lt;td&gt;0% (empty output)&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;llama3.2:3b-instruct&lt;/td&gt;
&lt;td&gt;q2_K&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;llama3.2:3b-instruct&lt;/td&gt;
&lt;td&gt;q4_K_M&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;llama3.2:3b-instruct&lt;/td&gt;
&lt;td&gt;q5_K_M&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;llama3.2:3b-instruct&lt;/td&gt;
&lt;td&gt;q8_0&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;mistral:7b-instruct&lt;/td&gt;
&lt;td&gt;q2_K&lt;/td&gt;
&lt;td&gt;80%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;mistral:7b-instruct&lt;/td&gt;
&lt;td&gt;q4_K_M&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
    &lt;tr&gt;
&lt;td&gt;mistral:7b-instruct&lt;/td&gt;
&lt;td&gt;q5_K_M&lt;/td&gt;
&lt;td&gt;80%&lt;/td&gt;
&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Some cells above are empty because they would not fit on the gpu of the nano, so no point in running a test for a model that will never perform as needed due to hardware limitations.&lt;/p&gt;

&lt;p&gt;The numbers are based on a pool of 10 questions, so this is why the numbers are so perfectly precise. Obviously this is simple high level test, but I wanted to work through this fully. Having gone through the motions, I know that the rabbit hole is deep and vast and this is barely the surface. But from simple test point of view for my use case of quiz generation, qwen2.5:3b-instruct takes the cake from the bakery to the house. Guess ima have a slice once I recombobulate my app, switching from llama3.2:3b-instruct to qwen ~ a task for another day. &lt;/p&gt;

&lt;p&gt;I'm sure many of you reading this have seen other benchmarks elsewhere. I'd love to have some peer review here to tell me if I'm kind of on point here or if my data looks odd. Feel like I'm falling into a dark trap of testing things. I know others have done this and there is other information out there, but what kind of actual appreciation for the technology does that offer? &lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>nvidia</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Jetson Nano: Ollama &amp; Optimal Quantization</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sun, 05 Jul 2026 16:06:31 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/jetson-nano-ollama-optimal-quantization-2de8</link>
      <guid>https://dev.to/annavi11arrea1/jetson-nano-ollama-optimal-quantization-2de8</guid>
      <description>&lt;p&gt;I am delighted to announce that a user reported dysfunction so that I could go down the rabbit hole of fixing it. Messing around locally is one thing, but building a tolerable app for end users has other considerations when using a ‘local’ AI. This led to interesting findings about the limitations of hardware and gaining a high-level understanding of quantization and it's importance. I also explain how to creatively get around limitations. It's called flippy card, and it's an app that helps you study via custom uploaded content. Wanna see it? It's here: &lt;a href="https://flippycard.annavillarreal.com/" rel="noopener noreferrer"&gt;Flippycard&lt;/a&gt;&lt;/p&gt;





&lt;h2&gt;
  
  
  Problems:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ollama was stuck behind cloudflare in a local loop.&lt;/li&gt;
&lt;li&gt;Ollama needs to be accessed outside of systemctl with config file.&lt;/li&gt;
&lt;li&gt;Ollama was running painfully slow, and needed to set it to use GPU, not CPU. &lt;/li&gt;
&lt;li&gt;Had to build Ollama from source and tell it to use GPU instead. &lt;/li&gt;
&lt;/ul&gt;





&lt;h2&gt;
  
  
  Implementations:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Make sure Ollama goes through cloudflare tunnel.&lt;/li&gt;
&lt;li&gt;Create configuration file so that Ollama is reachable externally.&lt;/li&gt;
&lt;li&gt;Build from source to save resources, Docker is too resource intensive for Jetson Nano to be performant.&lt;/li&gt;
&lt;li&gt;Increase speed by switching from CPU -&amp;gt; GPU, you need to be explicit about these things.&lt;/li&gt;
&lt;li&gt;Keep a watchful eye on system resources to make sure the Nano is not at risk of crashing.
I also added a Notes section to my new techdocs page to start documenting implementations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built from source to spare resources on the jetson orin nano which took about 30 minutes. I had concerns about pushing my 8GB of ram to its limit, which is a very valid concern. I need to keep it as lightweight as possible. As much as a docker container appealed to me, it is slim-pickin’s on a budget. &lt;/p&gt;

&lt;h3&gt;
  
  
  Building from source steps:
&lt;/h3&gt;

&lt;p&gt;Step 1: Install CUD toolkit + cmake with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Sudo apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; cuda-toolkit-13 cmake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Install Go (arm 64):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Curl &lt;span class="nt"&gt;-LO&lt;/span&gt; https://go.dev/dl/go1.24.4.linix-arm64.tar.gx &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; /usr/local &lt;span class="nt"&gt;-xzf&lt;/span&gt; go1.24.4.linux-arm64.tar.gz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm &lt;/span&gt;go1.24.4.linux-arm64.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Add Go and CUDA to PATH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Echo ‘export &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/usr/local/bint:/usr/local/cuda-13/bin’ &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; esport &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/usr/local/go/bin:/usr/local/cuda-13/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Clone and build ollama with sm_87:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Git clone https://github.com/ollama/ollama /home/anna/ollama-src &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; /hom/anna/ollama-src &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;CUDA_ARCHITECTURES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;87 cmake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This whole process took roughly 30 minutes.&lt;/p&gt;





&lt;h2&gt;
  
  
  Effeciency
&lt;/h2&gt;

&lt;p&gt;I wanted to share this process easily, so I connected the gmail MCP server to claude so I can send emails of the process summary to myself. &lt;/p&gt;

&lt;p&gt;Maximizing efficiency on the jetson nano was a good choice. I really don't want to be managing a bunch of documentation from my server, so I've created a new place to document my journeys on my new techdocs page. I built this while ollama was building. Understanding resource considerations, I asked claude to also build me a new page for me to put all my tech findings only if it didn't push my resources on my tiny server to the limit - knowing the process at hand was of the utmost importance. It analyzed the situation, gave me real feedback, and told me what could be done since I was already pushing the limits of hardware capabilities with my current install. This was a great insight to not crash the PC while an important process was running. Since everything was already running I was able to add new routes easily with a few lines. Of course I realize I could have done this on another computer, but it’s fun to push the limits of hardware.&lt;/p&gt;





&lt;h2&gt;
  
  
  Quantization - New Topic (for me)
&lt;/h2&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“Quantization is the process of reducing the precision of a digital signal, typically from a higher-precision format to a lower-precision format.” &lt;a href="https://www.ibm.com/think/topics/quantization" rel="noopener noreferrer"&gt;(Brian Clark, IBM)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After finally getting everything to work, the request took 13 minutes and 20 seconds using the Q8_0 version. This is where I learned about quantization. I then tried another variant, Q4_0 to improve the results. &lt;/p&gt;





&lt;h3&gt;
  
  
  Benchmarks
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbc5jp4sjdd5g8d554avs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbc5jp4sjdd5g8d554avs.png" alt="cyber level" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the benchmark breakdown of Q8_0 vs Q4_K-M quantization:&lt;/p&gt;

&lt;p&gt;Since the bottleneck was "model doesn't fit in available GPU memory," we tested a smaller quantization of the exact same model (llama3.2:1b), rather than switching to a different, weaker model family.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Q8_0 (original)&lt;/th&gt;
&lt;th&gt;Q4_K_M&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model file size&lt;/td&gt;
&lt;td&gt;1.5 GB&lt;/td&gt;
&lt;td&gt; 808 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU layers loaded&lt;/td&gt;
&lt;td&gt;3–9 of 17&lt;/td&gt;
&lt;td&gt;17 of 17 (100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generation speed&lt;/td&gt;
&lt;td&gt;~1.2–1.35 tok/s&lt;/td&gt;
&lt;td&gt;~30.7 tok/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real 971-token test&lt;/td&gt;
&lt;td&gt;13m 20s&lt;/td&gt;
&lt;td&gt;~35–45s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Q8_0 (original) Q4_K_M (new)&lt;br&gt;
Model file size 1.5 GB 808 MB&lt;br&gt;
GPU layers loaded 3–9 of 17 17 of 17 (100%)&lt;br&gt;
Generation speed ~1.2–1.35 tok/s ~30.7 tok/s&lt;br&gt;
Real 971-token test 13m 20s ~35–45s (estimated at this rate)&lt;/p&gt;

&lt;p&gt;That's roughly a 25x speedup, because the entire model now fits on the GPU instead of mostly running on the slow CPU path. Amazing! But what's the catch? &lt;/p&gt;





&lt;h3&gt;
  
  
  Issues
&lt;/h3&gt;

&lt;p&gt;Q4_K_M is fast but produced malformed output sometimes.&lt;/p&gt;

&lt;p&gt;Before switching, ran 6 back-to-back test generations with Q4_K_M to check reliability, since lower-precision quantization can be less consistent. &lt;/p&gt;

&lt;p&gt;Here's what happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 of 6: perfectly valid JSON, correct structure&lt;/li&gt;
&lt;li&gt;1 of 6: valid JSON, but used a slightly different field name than expected&lt;/li&gt;
&lt;li&gt;3 of 6: malformed JSON (e.g., a mismatched bracket) that would have crashed the app's parser outright&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's roughly a 50-65% failure rate per attempt. I cannot knowingly ship that, even with a massive speed improvement.&lt;/p&gt;





&lt;p&gt;So how do we handle the error-prone behavior of Q4?&lt;/p&gt;

&lt;p&gt;Rather than giving up on the faster model, automatic retry logic was added to the app itself. If the model's response is malformed, the app now silently tries again up to 3 times before showing an error. Because each Q4_K_M attempt only takes about 30-45s, even a worst-case 3 attempts is still far faster than a single guaranteed-slow Q8_0 request, while pushing the effective success rate up to roughly 85-95%.&lt;/p&gt;

&lt;p&gt;This handles the potential parsing errors gracefully. Since Q4 is 25x times faster, the client won’t really feel it.&lt;/p&gt;





&lt;p&gt;Side note: I noticed my Jetson had the “super” abilities after a month of setting it up. Don’t do what I did. Check for super abilities first. It’s a free download. XD&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>👾 🧚🏼‍♀️Maximizing Fable for Life Admin</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sat, 04 Jul 2026 12:31:09 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/maximizing-fable-for-life-admin-c62</link>
      <guid>https://dev.to/annavi11arrea1/maximizing-fable-for-life-admin-c62</guid>
      <description>&lt;p&gt;TLDR: The most powerful AI on the planet, only a few days of access. Maximize it.&lt;/p&gt;





&lt;p&gt;I'd first like to give credit where it's due: &lt;a class="mentioned-user" href="https://dev.to/trickell"&gt;@trickell&lt;/a&gt; - Thank you for sharing Network Chuck's youtube video with me. The reference video is found here guys if you missed it: &lt;a href="https://www.youtube.com/watch?v=YC77Lb_cN6c" rel="noopener noreferrer"&gt;Network Chuck's Video on Fable&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;I first started by creating a nice template for tech documentation for personal use. It created a beautiful piece of work in about 5 minutes - something I could easily expand on in the future. Here is what it generated for me with after a one or two careful prompts:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rn97tebs0lfvnda6lp2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rn97tebs0lfvnda6lp2.png" alt="tech docs by fable" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;
Clean UI, Easy Navigation! Created this personal reference guide for studying for CCNA (Network Chucks Summer of CCNA)



&lt;p&gt;Wanna see it? It lives here: &lt;a href="https://techdocs.annavillarreal.com/" rel="noopener noreferrer"&gt;Techdocs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But after learning about the true span of Fable's power, I started asking the serious questions, the ones that are life-changing. How can I increase my quality of life based on my resume, experience, and current life circumstances? I wrote about 2 pages of life issues that needed fixing - you know the stuff that slowly eats away at your soul, like student loan debt and people that are challenging to work with? Yes - I told it my biggest issues and instructed it to give me actionable plans that are free or low-cost. Even fable told me that this was a lot. 😅&lt;/p&gt;





&lt;h2&gt;
  
  
  Getting Organized
&lt;/h2&gt;

&lt;p&gt;Knowing the scope of my own problems I knew that my thoughts and processes had to be organized. Luckily for me, I remembered I had a good place to do that. A place that Fable could connect to and place documentation in place for me with checklists, notes, summaries and actionable plans. That app is called Notion, and some of you may have heard of it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv42f8yc3g8lmkemcpwb2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv42f8yc3g8lmkemcpwb2.png" alt="Notion documentation to reference later" width="799" height="289"&gt;&lt;/a&gt;&lt;/p&gt;
No one is going to organize your life for you, no one, except for AI







&lt;p&gt;I couldn’t think of a better place for lightning fast critical life-admin documentation on the spot. And I can tell you, this integration works like a charm, and I highly recommend it. For a busy person with a million ideas, this is great.&lt;/p&gt;





&lt;h2&gt;
  
  
  Anxiety Relief
&lt;/h2&gt;

&lt;p&gt;I had a tremendous amount of anxiety about my pending student loans. After bringing things to light with Fable, I realized that even though I am forced to make payments, it would be entirely manageable. I had massive fears about this because of all the ongoing litigation. Fable helped me think clearly through this - and I found the solution that would best work for my particular position it would seem.&lt;/p&gt;





&lt;h2&gt;
  
  
  Future Hope
&lt;/h2&gt;

&lt;p&gt;I fed it my resume, my linked in, my server website. I told it my struggles about finding work although feeling quite capable. It made me realize something. Even though Junior dev positions are a wasteland at the moment, fable was able to reframe my current position for me in an elegant manner. &lt;/p&gt;

&lt;p&gt;Direct copy from fable: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You are not "a junior dev in a dead market." You are a hybrid: IT support + full-stack dev + technical writer with a real audience + CCNA in progress + self-hosted infrastructure experience. Pure junior dev roles are brutal right now, but hybrid roles are NOT&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;… monumentally wicked powerful outlook rescoping!&lt;/p&gt;

&lt;p&gt;In less than an hour, fable has given me a greater peace of mind, hope, and actions I can work on right now to improve my life and the life of those around me. If you haven’t messed with fable, times a-ticking, go do it now.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>mentalhealth</category>
      <category>productivity</category>
    </item>
    <item>
      <title>👾 Server Access Logs with GoAccess</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sun, 21 Jun 2026 23:49:41 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/server-access-logs-with-goaccess-333d</link>
      <guid>https://dev.to/annavi11arrea1/server-access-logs-with-goaccess-333d</guid>
      <description>&lt;p&gt;Part 1: &lt;a href="https://dev.to/annavi11arrea1/self-hosting-experience-with-jetson-orin-nano-and-ollama-5a9c"&gt;Self-hosting on Jetson Orin Nano&lt;/a&gt;&lt;/p&gt;





&lt;h3&gt;
  
  
  👽 Jetson Orin Nano Web Server Follow-up 👽
&lt;/h3&gt;

&lt;p&gt;Cool! Now that the mini web server is up and running, how can I see web traffic easily? I discovered GoAccess recently, which is a free and open source tool for checking out server logs in real time. There are two way to view it. At first I was happy to just see nicely-parsed server logs in the terminal. Ahhhh, organization! It gives you a bunch of interesting stuff to look at.&lt;/p&gt;

&lt;p&gt;Here is what the terminal view looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flav1ura1myngxxin6gtk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flav1ura1myngxxin6gtk.png" alt="goaccess terminal view" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;
Dats cool







&lt;p&gt;You know, inviting traffic to a webserver invokes anxiety. Having half an idea of what is happening helps ease tension for sure. I was really excited to find this tool. You can open go access in the terminal to display different information with different views. I will leave the explaining to the official documentation found here: &lt;a href="https://goaccess.io/get-started" rel="noopener noreferrer"&gt;GoAccess Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But the web developer in me was super excited to find a very human-readable html version readily available. Using a reverse proxy through nginx, you can view all the stats on a web page locally. It also allows you to pick a theme and customize how the information is displayed. Be sure to check out the settings and chart options!&lt;/p&gt;

&lt;p&gt;Here is what the html view produces:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7g6a2pcn65uppscfl944.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7g6a2pcn65uppscfl944.png" alt="goaccess html view" width="799" height="399"&gt;&lt;/a&gt;&lt;/p&gt;
Stats for silly hoomins.







&lt;p&gt;Idk about you, but this is my super exciting find for the day.&lt;/p&gt;

&lt;p&gt;I think my next step is to connect an agent that reads the logs and alerts me on set parameters.&lt;/p&gt;

&lt;p&gt;I'm interested to hear what tools all of you use to enhance web server monitoring?&lt;/p&gt;

&lt;p&gt;What's the best agent for web analytics, in your opinion?&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>learning</category>
      <category>linux</category>
    </item>
    <item>
      <title>⚡️Self-Hosting Experience with Jetson Orin Nano and Ollama 🦙</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sat, 20 Jun 2026 19:02:46 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/self-hosting-experience-with-jetson-orin-nano-and-ollama-5a9c</link>
      <guid>https://dev.to/annavi11arrea1/self-hosting-experience-with-jetson-orin-nano-and-ollama-5a9c</guid>
      <description>&lt;p&gt;Part 2: &lt;a href="https://dev.to/annavi11arrea1/server-access-logs-with-goaccess-333d"&gt;GoAccess Logs&lt;/a&gt;&lt;/p&gt;





&lt;p&gt;I don't know where to begin. This is a long story, but it all started when I saw that DEV was having a ‘finish-it--up-a-thon’. I was instantly interested, with a particular project in mind. I’ve been working on govend on and off since 2024. It’s something I started in a web developer apprenticeship. When I first ‘launched’ this ‘minimum viable product’ I was so proud of it. Every line of ruby, written by me. - No assistance from AI. The nokogiri web scraper implementation,  figured out all on my own. It was ugly and I had issues with dates not saving properly in the database with the scrapers. Only recently after deciding I was going to finish my project did I address this. If I am going to ship I refuse to ship slop if it is within my knowledge and power. This is the latest before and after shot I have here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzevtipby4i57ubc46xxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzevtipby4i57ubc46xxz.png" alt="before and after" width="799" height="300"&gt;&lt;/a&gt;&lt;/p&gt;
Before on the left, after on the right







&lt;h3&gt;
  
  
  Figuring Out Requirements
&lt;/h3&gt;

&lt;p&gt;I really gave myself an undertaking. I didn’t realize how much work I had left to do. Given other priorities I was sadly not able to participate in the DEV challenge. But it gave me the itch of motivation I probably needed. The biggest part of this challenge for me was to successfully self-host my app locally. I’m using AI and I did not have a personal 'server' on my local network. I had everything running off other services… render, neon, vercel, heroku, github pages. &lt;/p&gt;

&lt;p&gt;I quickly realized that I had a problem when I wanted to use AI in my apps and allow users to use the AI. One of the issues I ran into is that AI cloud servers are expensive. Another issue I ran into is connecting cloud services to a local agent. In my govend app, I created a chat interface a while back where users can talk to ollama and ask about events during certain dates, or to find events by location. This was easy to do locally, I had ollama reach out to algolia with the users request, and bring back related events. But I want to do this… not on my personal computer.&lt;/p&gt;

&lt;p&gt;I must admit all of this is a scary leap for me, but a necessary one. I looked into methods of affordable self-hosting and after some digging, I was convinced that the Jetson Orin Nano was the answer. It’s designed to handle AI tasks on small models. Good enough for my use case. And I was really liking how it was a one-and-done situation, no need to buy external little this-and-thats. I’m already doing a big new undertaking, don’t wanna complicate it. I’m not gonna spend $100 or whatever it is now a month on a cloud ai server - I’ll spend a few hundred and be done. (For now, evil laugh)&lt;/p&gt;

&lt;p&gt;What I actually got:&lt;/p&gt;


&lt;ul&gt;

&lt;li&gt;Nvidia Jetson Orin Nano Developer Kit&lt;/li&gt;

&lt;li&gt;Pack of USBs&lt;/li&gt;

&lt;li&gt;nvme hard drive&lt;/li&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj3x1beo43jju1lhllngx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj3x1beo43jju1lhllngx.jpg" alt="jetson orin nano" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;
Jetson Orin Nano



&lt;h3&gt;
  
  
  Tips
&lt;/h3&gt;


&lt;ul&gt;

&lt;li&gt;After seeing some posts online and speaking to some people, I steered clear of even bothering with an SD card. I’d have to recommend you do the same if you go this route. I have zero regrets.&lt;/li&gt;



&lt;li&gt;They have some good documentation online for setup, and it’s pretty straightforward when all the stars are aligned. But let me tell you how they weren’t.&lt;/li&gt;



&lt;li&gt;So, depending on the current configuration of your nano, it will likely need updates at boot. The updates must be allowed to run for compatibility reasons. No problem. &lt;em&gt;However,&lt;/em&gt; the screen I was using for setup was something the cat dragged in... &lt;/li&gt;






&lt;h3&gt;
  
  
  Drama Begins
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukr1vd7sl8ae99hqchia.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fukr1vd7sl8ae99hqchia.jpg" alt="what the cat dragged in" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;
Issue-laden monitor - This is a monitor that was mounted in an RV and dragged across the country. It was then abandoned by a family member which I made quick use of. It was then given back, and then abandoned again. It has loose pieces inside that rattle, the bezel is missing, and it decides when and where it has a problem. I was excited to connect it so I could play with my nano.







&lt;p&gt;So that little piece of information that pops up and says ‘enter yes to continue’, I never saw that during my first attempt. I kept retrying over and over, never seeing the screen I needed to see. &lt;/p&gt;

&lt;p&gt;I’ll tell you why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If my monitor is already on and then I plug in the nano, the screen goes into sleep mode and hibernates, within 1 second of me plugging it in. It goes to sleep while the nano is still booting.&lt;/li&gt;
&lt;li&gt;By the time I press the button on the screen to wake it back up, the nano has already passed a crucial input moment, so I never saw it! &lt;/li&gt;
&lt;li&gt;The only reason I found this to be the case was because I started reading through troubleshooting with a fine tooth comb. I figured out I was waiting for an input screen I was never going to see because of timing. And yes I did look into the monitor settings, no hope there.&lt;/li&gt;
&lt;/ul&gt;





&lt;p&gt;At some point, I finally got the thing to boot by plugging in the orin nano and pressing the button on the monitor at the exact same time. Things started loading, packages zipping across the screen, general excitement. And then, I waited. For like, half an hour. Is it broken? What is happening? General panic. &lt;/p&gt;

&lt;p&gt;After what seemed to be rough 45 minutes to an hour, I pulled the plug. Something didn’t seem right. I carefully plugged in the nano and pressed the monitor power button at the same time. It booted, and asked me for a login. Login? What login? I haven’t made a login? That usb became read-only afterward, so I couldn't reformat it normally. I ended up using a different usb for the installer.&lt;/p&gt;

&lt;p&gt;Now armed with the knowledge of the scope of my personal problems, I create a new usb, ready to battle with peripherals. It works correctly when you both know what your problems are and how to handle them. &lt;/p&gt;





&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy51fdn399grx68o0wprv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy51fdn399grx68o0wprv.jpg" alt="tiny server" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;
Got a mini hdmi cable so I could get rid of the obnoxious pile of a screen I was using prior. Way better!



&lt;h3&gt;
  
  
  Learning Self-Hosting
&lt;/h3&gt;

&lt;p&gt;In the days (weeks?) that followed, I got everything setup. I learned how to self host my own apps on the nano. Having cleared out all of my heroku’s and render’s I had a small pool of domain names at my disposal as well. I spent a few days really trying to get govend to a proper state so I could share my app and help vendors and artists find events to vend at and manage their events in one place. As a vendor of 5 years I know this is needed. Small businesses are the wild west and don’t have too many specialized tools. I really wanted to see it come alive. I could spend forever on it, but I have to make it available at some point. &lt;/p&gt;

&lt;h4&gt;
  
  
  1 Ollama for 2 apps
&lt;/h4&gt;

&lt;p&gt;I also cleaned up my flippy card app that uses ollama for the generation of flashcards, a memory game, and self quizzes. I am able to use a single ollama instance for both of my apps. How awesome is that? And basically, since my database is separated from supporting services, my web server is basically just a little connecting hub for apps and services. Pretty cool! I think its relevant to insert here that AI can be a security nightmare if you don't button stuff up. &lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Security
&lt;/h4&gt;

&lt;p&gt;I learned about securing things, using proxies, and closing unused ports. I asked a couple trusted people to take a peek at my app and I had someone run a scan on it before sharing with their bot as a security measure. I openly admit I had not considered the ai security too heavily, and things were found and addressed. It’s interesting to be fairly confident about an app and then AI throws a wrench into everything. I did not anticipate all the time that has to be spent on security. Massive learning experience, and had me groaning at my server towards the end.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fast Build from Experience
&lt;/h4&gt;

&lt;p&gt;I installed claude code and used it to help me build out a server ‘hub’ page quickly, where I share some live apps, blog posts, and relevant links. After a carefully chosen prompt it built quickly with my aesthetic in mind. I proceeded to tweak it, adding a carousel to the projects section on top so it would look different from the bottom blog section. I pulled in code I used in previous projects to let Claude know what I was trying to do. Having built a bunch of stuff prior, it made constructing this page incredibly simple.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn3kzrz83of4zw938jbzu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn3kzrz83of4zw938jbzu.png" alt="new server hub" width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;
Look at the tiny server go!







&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;


&lt;ul&gt;

&lt;li&gt;I took the feedback of hermes and fed it to claude to quickly implement solutions like rate limiting and endpoint security. On too many attempts, the account will lock for a timed period. I discovered so many security vulnerabilities quite frankly I'm embarrassed to admit. The part that is not so embarrassing is that I was intelligent enough to check myself before sharing.&lt;/li&gt; 


&lt;li&gt;The app I really wanted to highlight here was govend, but honestly, I’m kind of gushing over my “server hub page” I created as a result of all this. I have been making little ‘profile’ apps here and there throughout time, each one better than the last. I decided instead of a profile page per say, I wanted a central hub to find all things related to me, the developer. Not a resume or profile. Just a ‘hub’. My microserver. Welcome, and thanks for looking. I built this.&lt;/li&gt;



&lt;li&gt;AI helped me implement and identify baseline protections, and I treated security review as essential. I learned about including a security.txt file for bug reporting. A fellow member has a nice article about security.txt: &lt;a href="https://dev.to/route06/what-is-securitytxt-and-how-can-it-help-improve-website-security-3kij"&gt;security.txt article&lt;/a&gt;
&lt;/li&gt;


&lt;p&gt;I would have to say a large part of cleanup involved making sure everything is secure as possible. &lt;/p&gt;

&lt;h4&gt;
  
  
  Here is a breakdown:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;I added rate limiting, progressive lockouts, and CAPTCHA hooks.&lt;/li&gt;
&lt;li&gt;Added Security headers&lt;/li&gt;
&lt;li&gt;Added Content Security Policy, Removed the unsafe-inline and unsafe-eval directives from script-src, and removed architecture leaks.&lt;/li&gt;
&lt;li&gt;Responsible disclosure - Created /.well-known/security.txt with contact email&lt;/li&gt;
&lt;li&gt;I configured the server firewall. Initially, I was having issues getting it to work, and then I discovered that there was a table compatibility issue I needed to address. Addressing security alone was added another day or two.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;What do you think?&lt;/p&gt;


&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;

</description>
      <category>ubuntu</category>
      <category>nvidia</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>🐝 Real-Life Debugging Story + Home Network Analysis: Peekyport 🫣</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sat, 16 May 2026 16:44:11 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/real-life-debugging-story-home-network-analysis-peekyport-a10</link>
      <guid>https://dev.to/annavi11arrea1/real-life-debugging-story-home-network-analysis-peekyport-a10</guid>
      <description>&lt;p&gt;There is, for the second time in a month, a yellow jacket in the basement. You know what else is in my basement? My favorite machine. &lt;/p&gt;

&lt;p&gt;The first time this happened, it was early and I was getting ready for work. I saw something moving on my bottle of heat-protectant spray. It looked like a really fat caterpillar, but it had wings. I sat there for a second pretending like nothing was happening. It was distracted by the smell of the heat protectant. &lt;/p&gt;

&lt;p&gt;I slowly turned off my hair straightener and set it down, backing away semi normally. (Ladies, who &lt;em&gt;hasn't&lt;/em&gt; done their hair in front of their device. 😂) I realized that this was not an average bee. This was not a regular puffy bumble bee, or a sweat bee, or a honey bee. This bee looked like it was a soulless attacker.&lt;/p&gt;

&lt;p&gt;I alerted my boyfriend immediately. I did not want anything bad to happen to him while he was sleeping. These yellow jackets attack for no reason. While I was at work, he picked a fight with the yellow jacket and thankfully won. I was so scared for him. The following morning, I saw a dead yellow jacket inside my computer case. 😭 &lt;/p&gt;

&lt;p&gt;That sounds like 2 yellow jackets so far. After a month passes, I am sitting there minding my own business and BAM, another one! I saw it just barely land on the top of the bookshelf out of the corner of my eye! I think to myself: "**** this, I am moving out!"&lt;/p&gt;

&lt;p&gt;My boyfriend got traps and crack sealer for the basement, seeing my state of petrification. They have been setting out for a few days. But he went to work and could not save me until he came back. (Yes, it is &lt;em&gt;save the princess&lt;/em&gt; when there is a direct threat buzzing around.) Therefore, I must stay up on the second floor. I am not moving until I see a dead bee. I have not been in the basement and I absolutely refuse to go down there until there is undeniable evidence. &lt;/p&gt;





&lt;h3&gt;
  
  
  But my computer is in the basement...
&lt;/h3&gt;

&lt;p&gt;My 7-year-old mac is no match for my 2-year-old custom desktop. I must use it. But how? I had one of those moments where a tiny lightbulb went on. I wanted to get to a specific project of mine so I could share the tiny excitement with everyone.&lt;/p&gt;

&lt;h4&gt;
  
  
  Remote Access for the win
&lt;/h4&gt;

&lt;p&gt;I remembered that I installed a remote app on my phone so I could see my pc screen whenever and wherever. (LOVE that btw). Since it's all synced through google anyways, I was like well hey, let me pull that bad boi up! Like butter, I see my pc desktop. I messed around with it but my pc desktop is much wider than my laptop, so it wasn't a perfect situation. I discovered I couldn't record my pc screen while remoting in from mac. I tried it a few times with no luck. (What's up with that?) &lt;/p&gt;

&lt;p&gt;Then I remembered I had made a shared folder for my local network. (Just to prove to myself I knew how at the time.) I saw that it was still there. Ah! So this is what networking is really for! To save us from ourselves and evil bugs! &lt;/p&gt;

&lt;p&gt;So then, I copy over the project folder of interest to shared location, and then put a copy on my macbook. So, as you likely know, we can not just open up a project and run it on mac, if it was built on a windows pc. There is some &lt;em&gt;convertabobbing&lt;/em&gt; involved. I had copilot CLI do the fantabulous converting.&lt;/p&gt;





&lt;p&gt;All of this so I could share:&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Peekyport
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa404g7aqzjv3p125f6or.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa404g7aqzjv3p125f6or.png" alt="Peekyport Logo" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a home network analysis and organization tool that I am building from scratch. Well, yes from scratch but ai-assisted because I am just learning Java. Which btw Java appears to be more verbose than Python and Ruby I am also finding. Why do I have to tell you it's a string? Python and Ruby are not like that. I digress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;App Name: Peekyport&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tech used: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaFX&lt;/li&gt;
&lt;li&gt;Nmap&lt;/li&gt;
&lt;li&gt;tshark&lt;/li&gt;
&lt;li&gt;Custom CSS&lt;/li&gt;
&lt;li&gt;Draggable topology&lt;/li&gt;
&lt;li&gt;Local storage&lt;/li&gt;
&lt;li&gt;and an interface to connect your router of choice.&lt;/li&gt; 
&lt;/ul&gt;

&lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; a web app. It is a thick-client JavaFX network tool with direct OS integration and minimal dependency footprint. I made it over-the-top with "levels" to represent the floors in a building. One can place nodes around and get a better idea of what your topology actually looks like! &lt;/p&gt;

&lt;p&gt;I built this because all the cool-looking tools are not free, and I wanted an engaging one. This is by no means perfect or a finished product, but I wanted to share my excitement. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Layout Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rmo9jmqz86ehrqvviut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rmo9jmqz86ehrqvviut.png" alt="Peekyport Overview" width="799" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before Peekyport becomes interesting, we need to scan the network in question. You can run a lightweight scan that covers only the most common ports, or a deep scan which would take much longer. A light scan is adequate for tinkering purposes. When the scan is run, I created a visual console display so the actual scanning can be seen in real time with a progress bar. The visual feedback is nice to clarify that things are actually happening. Bonus: it looks cool.&lt;/p&gt;

&lt;p&gt;Here you can see a scan in progress in Peekyport:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5ao21wpwo856jj796vp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5ao21wpwo856jj796vp.png" alt="Scan in progress" width="799" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After scanning your network, nodes will display in the central area in the Topology Tab. With each node you can edit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name&lt;/li&gt;
&lt;li&gt;Category&lt;/li&gt;
&lt;li&gt;Group&lt;/li&gt;
&lt;li&gt;Floor Number&lt;/li&gt;
&lt;li&gt;Shape and color to differentiate items&lt;/li&gt;
&lt;li&gt;Upload images to help you additionally identify&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14rat2hxn958z3ot71yx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F14rat2hxn958z3ot71yx.png" alt="Node interface" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect to your router by navigating to the router page and entering the details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdld9cjm5uzem7wx0xffw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdld9cjm5uzem7wx0xffw.png" alt="Connecting home router" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connecting your router, scanning your network, and comparing it to your wireshark packets gives you a good peek into possible security holes. This allows a user to draw actionable insights for tightening things up on a home network. Being careful with what you are exposing ensures you are less prone to security issues.&lt;/p&gt;

&lt;p&gt;Cool! Now having our basic network topology from the grass-roots network scan and our router connected to allow more specific details, we can run a small wireshark scan and import the saved pcap file. About 2,000 packets or so should give you enough to poke around with.  🤔&lt;/p&gt;

&lt;p&gt;Heading to the Web Traffic Tab, we select a packet capture for analysis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2te8a8vm95cbuv3felmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2te8a8vm95cbuv3felmg.png" alt="pcap file uplaoder" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a screenshot of the per device traffic activity after upload:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24nwkxqncve6acd6bz31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24nwkxqncve6acd6bz31.png" alt="Traffic by device" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depending on your scan and what network you are connected to, you will see the corresponding devices. On a wifi network scan, you will only see wifi links. If you run a  scan connected to ethernet directly, you will choose "hardwire" in the link view. If you do not have the right one selected, you won't see the links because they do not exist. Makes sense.&lt;/p&gt;

&lt;p&gt;I really, really like the network topology link visualization. I feel like I can gain a much better understanding by see what devices speak to each other, through what ports, and how much. Now I can confront household memembers when they overtake the network bandwidth, with my new network facts. Empowering, isn't it? 😂 JK, my bandwidth has actually not been a problem thanks to dynamic quality of service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ihns0epvg55a3ukf9lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ihns0epvg55a3ukf9lw.png" alt="logical wifi links" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Network safety by severity is found in the safety tab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibddyn5qlyh83ni2f88x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibddyn5qlyh83ni2f88x.png" alt="Overview findings" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This provides a snapshot of home network security. Many internet users do not have the need or resources to have a fancy enterprise grade network solution for their home. This app empowers a single individual to investigate their home network with a home router, keeping data secure by running it locally.&lt;/p&gt;





&lt;h3&gt;
  
  
  For everyone
&lt;/h3&gt;

&lt;p&gt;This app pulls web traffic together with IP addresses, mac addresses, and conversations between these addresses to gain insights about what can be addressed to improve security. It's super nice to be able to monitor traffic in such a specific modular way, with each device and all of is ports listed. &lt;/p&gt;

&lt;p&gt;It makes learning about your home network fun and de-mystifies the seemingly intangible network activity for all. I think every home network should have something like this. &lt;/p&gt;





&lt;h3&gt;
  
  
  For the future
&lt;/h3&gt;

&lt;p&gt;I am struggling a bit with the drag and drop interface, it behaves in an unexpected manner and there is a lot of weird layering and processes happening if other processes happen. It was so bad at one point I was about to trash the whole thing. But I have been powering through it, and I am slightly less frustrated although it's still not great. The data part is working gracefully. I will continue to fight with the UI until I am satisfied. (So, no end in sight for the foreseeable future. LOL)&lt;/p&gt;

&lt;p&gt;What network analysis tools have you built? Comments, tips, questions? &lt;/p&gt;

&lt;p&gt;Thank you for reading my tiny story. 💜&lt;/p&gt;

</description>
      <category>java</category>
      <category>network</category>
      <category>javafx</category>
      <category>security</category>
    </item>
    <item>
      <title>Circuits: Bit-Banging, SPI, and CPLD</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Thu, 14 May 2026 22:53:39 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/circuits-bit-banging-spi-and-cpld-3b5o</link>
      <guid>https://dev.to/annavi11arrea1/circuits-bit-banging-spi-and-cpld-3b5o</guid>
      <description>&lt;p&gt;TLDR: A small exploration of the use case of hardware over software. &lt;/p&gt;





&lt;p&gt;"Bit-banging" ...what?&lt;/p&gt;

&lt;p&gt;Apparently, bit-banging is when you are &lt;em&gt;trying to do with software what should be done with hardware&lt;/em&gt;. What an entertaining thought. Has anyone done this? I would love to hear your story.&lt;/p&gt;

&lt;p&gt;This is that area in computer science where software developers probably start to stick up their nose. Circuit? &lt;em&gt;Excuse me&lt;/em&gt;? 😆 Leave that to the hardware engineers. &lt;/p&gt;

&lt;p&gt;Guys, we have to play nice and communicate here. Did you know that when it comes to development, some argue there is up to 7,000 communication protocols globally? In all fairness, most of us only use a handful. But still, if you can handle the vast majority of communication protocols for web development, surly you can handle the small amount that exist in hardware. The focus is on one today: SPI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SPI - Serial Peripheral Interface&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;A four-wire, high-speed, full-duplex protocol for synchronous communication between microcontrollers and peripherals&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In one of my classes, we had to come up with a project where we implemented a PLD into a circuit. I looked into use cases for such a thing, and discovered a CPLD is very useful in cases where timing is absolutely critical, or else the system would dysfunction. &lt;/p&gt;

&lt;p&gt;I happen to be a big fan of programmable LEDs.&lt;br&gt;
It is entirely possible to wire an ESP32 directly to an LED strip, but there are a lot of problems with connecting directly, and I have witnessed them in person. Challenges with the ESP32 include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It runs a multitasking operating system, and interruptions from wifi can disrupt timing precision.&lt;/li&gt;
&lt;li&gt;If the timing is off, the LEDs will display the wrong colors or glitch.&lt;/li&gt;
&lt;li&gt;Inconsistent timing resulting from this could lead to the wrong colors displayed.&lt;/li&gt;
&lt;li&gt;Disabling interrupts would also drop wifi packets, leading to intermittent connectivity and exacerbating the problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And returning to the concept of bit-banging...&lt;/p&gt;

&lt;p&gt;This is probably one of those topics that software engineers should pay closer attention to. Some things are best left to hardware. The bit-banging software approach to handling the circuit introduces more inconsistent timing due to wifi, timer, and serial port interrupts. The timing must be nearly perfect for it to work as expected. Bit-banging can lead to high CPU usage for moderate reliability.&lt;/p&gt;





&lt;p&gt;&lt;strong&gt;THE SOLUTION&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So what can be done to run our multitasking OS alongside a fluid light show? We can fool the audience by offloading the timing-critical LED driving to hardware. The ESP32 talks to a CPLD (complex programmable logic device) through a serial peripheral interface. In this arrangement we have a wire for data, clock, select, and ground. I was very excited to learn about how these connections all work, so I made a diagram that represents the physical connections between each set of circuits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hbse6lmsyz7f8pbdfr6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hbse6lmsyz7f8pbdfr6.png" alt="Circuit Overview" width="800" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives a high level understanding of our circuit structure. The CPLD takes the serial data from the ESP32 controller and uses memory to store the information. A pulse generator will also be built as part of the CPLD to make sure that we do not have timing issues. A unique feature of the SPI protocol is that it allows data to be transferred without interruption. This is the really important part. Instead of doing an internal eye roll over performance issues, I would encourage you to try it out. With these boards you don't even need to solder. You just connect the pins, like adult legos. Easy-peasey.&lt;/p&gt;

&lt;p&gt;Now, the speed of data transfer is determined by the frequency of the clock signal. This means that we can make the lights change faster or slower by controlling the frequency of the clock. &lt;em&gt;Cool&lt;/em&gt;. A faster clock speed means LEDs will update more frequently, and a slower clock speed will make them update in a slower manner.&lt;/p&gt;





&lt;p&gt;&lt;strong&gt;Let's Talk Real Life&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In real hardware, code is written to describe both parts of the CPLD. The synthesis tool converts it to actual logic gates and flip flops. The CPLD contains both the SPI receiver and the pulse generator (which controls the timing). &lt;/p&gt;

&lt;p&gt;A nice board that could be used in a project like this could be the Altera MAX II EPM240 CPLD Development Learning Board that I found online. In the picture below, we see the top row of input pins with the GND and +5V on the very right. The programmable logic of the CPLD happens inside of the central black square. On the bottom, a row of output pins is aligned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bzj3763udamet74iptc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bzj3763udamet74iptc.png" alt="ALtera Max II EPM240 CPLD" width="738" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Might have to try this out and see what happens. Am I stepping into the unseen madness that is hardware? It is uncertain, but very curious indeed Mr. Watson.&lt;/p&gt;

</description>
      <category>esp32</category>
      <category>learning</category>
      <category>circuits</category>
      <category>hardware</category>
    </item>
    <item>
      <title>You know you are a coder couple when...</title>
      <dc:creator>Anna Villarreal</dc:creator>
      <pubDate>Sun, 19 Apr 2026 11:29:18 +0000</pubDate>
      <link>https://dev.to/annavi11arrea1/you-know-you-are-a-coder-couple-when-8an</link>
      <guid>https://dev.to/annavi11arrea1/you-know-you-are-a-coder-couple-when-8an</guid>
      <description>&lt;p&gt;Are there many coder couples out there? It presents unique opportunities to poke around with things. Take this morning for example...&lt;/p&gt;

&lt;p&gt;I ask my significant others bot for advice about weather or not to wake him. His bot replies with unwavering logic, as usual.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltp88uwo7jp4ek9h5kr9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltp88uwo7jp4ek9h5kr9.jpg" alt="sleep defenses" width="800" height="821"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyone else with a tech savvy partner? I would love to hear your stories. (Or give me ideas.... shhhhhh! Haha.)&lt;/p&gt;

&lt;p&gt;He has since rolled over, in an attempt to access my track pad in his sleep. I can see revenge is eminent. 😂&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>ai</category>
      <category>openclaw</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
