<?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: Angel L. Valdés</title>
    <description>The latest articles on DEV Community by Angel L. Valdés (@alvaldesdev).</description>
    <link>https://dev.to/alvaldesdev</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%2F4213667%2F9074e796-51d7-4aa3-8b3c-b5467f243124.jpg</url>
      <title>DEV Community: Angel L. Valdés</title>
      <link>https://dev.to/alvaldesdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alvaldesdev"/>
    <language>en</language>
    <item>
      <title>I don't code alone: I lead a team of agents</title>
      <dc:creator>Angel L. Valdés</dc:creator>
      <pubDate>Mon, 02 Nov 2026 00:09:35 +0000</pubDate>
      <link>https://dev.to/alvaldesdev/i-dont-code-alone-i-lead-a-team-of-agents-3km3</link>
      <guid>https://dev.to/alvaldesdev/i-dont-code-alone-i-lead-a-team-of-agents-3km3</guid>
      <description>&lt;p&gt;At 12:25 on October 27, Netty was an &lt;code&gt;idea.md&lt;/code&gt; file. By 22:58 the same day, the app and its landing page existed, with 38 commits in between. By the 30th it had launched.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/introducing-netty/" rel="noopener noreferrer"&gt;Netty&lt;/a&gt; is a macOS menu bar app that tells you whether you're really online. The idea isn't original; similar apps already exist. What was interesting about those four days was something else: how I built it.&lt;/p&gt;

&lt;p&gt;I didn't write every line by hand. I also didn't ask an AI to "make me an app" and go grab a coffee. I worked like a project manager with a development team. Each agent was an independent developer that wrote code and tested it; I reviewed it and decided what came next.&lt;/p&gt;

&lt;p&gt;The best part was testing. The agent could use the Mac directly and run real integration tests while I watched. And when it came to the website, it could see what it was designing in a real browser. It had hands and eyes.&lt;/p&gt;

&lt;p&gt;This post is that workflow, piece by piece.&lt;/p&gt;

&lt;h2&gt;
  
  
  The full picture
&lt;/h2&gt;

&lt;p&gt;My stack has eight layers, each with one job:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Its job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Terminal&lt;/td&gt;
&lt;td&gt;Ghostty&lt;/td&gt;
&lt;td&gt;Where everything lives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workspaces&lt;/td&gt;
&lt;td&gt;herdr&lt;/td&gt;
&lt;td&gt;Keeps the agents running in parallel in order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version control&lt;/td&gt;
&lt;td&gt;Git and GitHub&lt;/td&gt;
&lt;td&gt;Gives each agent its own space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agents&lt;/td&gt;
&lt;td&gt;Gentle AI, Gentle Shell, and Engram&lt;/td&gt;
&lt;td&gt;Define how the agent works and what it remembers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser&lt;/td&gt;
&lt;td&gt;ego-browser&lt;/td&gt;
&lt;td&gt;Gives the agent eyes and hands on the web&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voice&lt;/td&gt;
&lt;td&gt;BetterWispr&lt;/td&gt;
&lt;td&gt;Lets me talk to the agents instead of typing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knowledge&lt;/td&gt;
&lt;td&gt;Obsidian&lt;/td&gt;
&lt;td&gt;My second brain, shared with the agents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgk55nbrbdf24zwuzhf1s.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgk55nbrbdf24zwuzhf1s.webp" alt="The whole stack: you, as project manager, talk through BetterWispr to four agents working in parallel in herdr inside Ghostty, each in its own worktree and following Gentle AI's rules. The agents use Engram, ego-browser, Obsidian, and Git with GitHub. As an extra, Tailscale and Moshi connect you from your phone." width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The terminal: Ghostty
&lt;/h2&gt;

&lt;p&gt;Almost everything happens in a terminal, so the terminal matters. I use &lt;a href="https://ghostty.org" rel="noopener noreferrer"&gt;Ghostty&lt;/a&gt; because it's fast and feels native on macOS, which is exactly what you want from the tool you keep open all day.&lt;/p&gt;

&lt;p&gt;Netty was the test. For four days I had several agents working at once, and Ghostty never froze or crashed. The Mac stayed cool, and I kept working in other apps in the meantime.&lt;/p&gt;

&lt;p&gt;All my configuration, for Ghostty and for every other tool in this post, lives in my &lt;a href="https://github.com/alvaldes/alvaldes.dots" rel="noopener noreferrer"&gt;alvaldes.dots&lt;/a&gt; repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F89v4olrpi6oaj73ra9cn.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F89v4olrpi6oaj73ra9cn.webp" alt="My alvaldes.dots repo on GitHub: one folder per tool, such as aerospace, ghostty, gh, btop, and git, with the description &amp;quot;My personal configuration&amp;quot;" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The workspaces: herdr
&lt;/h2&gt;

&lt;p&gt;One agent at a time falls short. While one writes the app, another can build its website. The problem is keeping track of them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://herdr.dev" rel="noopener noreferrer"&gt;herdr&lt;/a&gt; is a workspace manager for AI agents in the terminal. Each workspace is a project with its tabs and panes, and herdr detects which agent runs in each one and what state it's in, so you know when one needs you. Sessions stay alive after you disconnect, like tmux, and you can connect to them from another machine.&lt;/p&gt;

&lt;p&gt;I pair it with Git. For each agent I create a &lt;a href="https://git-scm.com/docs/git-worktree" rel="noopener noreferrer"&gt;worktree&lt;/a&gt;: a copy of the repo in its own folder, on its own branch. Each agent works in its worktree without stepping on the others, and at the end I merge each branch and resolve the conflicts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhb5ppf336pdc1dmxdldt.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhb5ppf336pdc1dmxdldt.webp" alt="My terminal running git log --oneline --decorate -24 in the Netty repo: the commits with their branches feat/landing, fix/landing-demo, fix/landing-nav, fix/landing-glass-shots, and fix/landing-nav-glass, already merged into main, and the v1.0.0 tag" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On Netty I worked with at least two: one for the app and one for the website. The app's agent sometimes split into more agents, one per feature or per independent unit of work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpuu3hqriftddlyllxg6h.webp" alt="herdr with three Claude Code agents working on Netty in parallel, each in its own worktree. The sidebar shows their state, and the landing page agent asks which layout I prefer before changing anything" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Video in the &lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;original post&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The agent layer: Gentle AI, Gentle Shell, and Engram
&lt;/h2&gt;

&lt;p&gt;An agent without rules is a new developer without onboarding: fast, eager, and able to break things with all the confidence in the world. This layer is the onboarding.&lt;/p&gt;

&lt;p&gt;All three tools come from &lt;a href="https://github.com/Gentleman-Programming" rel="noopener noreferrer"&gt;Gentleman Programming&lt;/a&gt;, Alan Buscaglia's project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Gentleman-Programming/gentle-ai" rel="noopener noreferrer"&gt;Gentle AI&lt;/a&gt;&lt;/strong&gt; is a discipline layer for agents. It defines how the agent works: when it asks, when it plans before writing, when it delegates to subagents, which skills it loads, and when it asks for a review before calling something done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb7crktcqyhck3zcuap2x.webp" alt="The official Gentle AI banner: a rose with the words Ecosystem, Framework, Workflows" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Gentleman-Programming/gentle-shell" rel="noopener noreferrer"&gt;Gentle Shell&lt;/a&gt;&lt;/strong&gt; is the workspace built on &lt;a href="https://pi.dev" rel="noopener noreferrer"&gt;Pi&lt;/a&gt;, a coding agent. It ships Pi with all of Gentle AI already loaded, plus agent orchestration, diff views, and usage monitoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4cals77pdu83xvbnssv2.webp" alt="The official Gentle Shell banner: a rose with the gentle-shell command and the words Ecosystem, Agent, One shell" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/Gentleman-Programming/engram" rel="noopener noreferrer"&gt;Engram&lt;/a&gt;&lt;/strong&gt; is the memory. An agent forgets everything when the session ends; Engram stores the decisions, the fixed bugs, and the conventions, and the agent gets them back next time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgib512ju817peegh213l.webp" alt="The official Engram banner: an elephant that says remember, sync, and recall, with the tagline One Brain. Local or Cloud." width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Engram was key on Netty. I had built &lt;a href="https://www.alvaldes.dev/blog/introducing-jump/" rel="noopener noreferrer"&gt;JUMP&lt;/a&gt;, another macOS app, before. When Netty started, the agent searched JUMP's memory for the mistakes it had made there and what it had learned, and didn't repeat them. One of those lessons: on JUMP, an unsigned build lost its Accessibility permission on every update. It didn't stop at the current project's context: it went looking in another one of my projects.&lt;/p&gt;

&lt;p&gt;Gentle AI does a lot more than fits here. What matters is the idea: the agent doesn't improvise how it works in every session. It always works the same way, and it remembers what it already learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  The browser: ego-browser
&lt;/h2&gt;

&lt;p&gt;An agent that writes a web page without seeing it is working blind. It can write correct CSS that looks wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lite.ego.app/" rel="noopener noreferrer"&gt;ego-browser&lt;/a&gt; is a Chromium-based browser built for humans and agents alike. The agent drives it from the terminal: it opens pages, clicks, fills in forms, and takes screenshots. And since it's the same browser I use, it has my sessions signed in.&lt;/p&gt;

&lt;p&gt;On Netty's website that changed the result. The agent designed, looked at the screenshot, saw what didn't work, and fixed it, without me having to describe every problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5ot3m0cxnlv5p3y9ajws.webp" alt="An agent goes through the Netty landing page in ego-browser: it checks the download button, takes a screenshot, scrolls through the sections, and opens a question in the FAQ" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Video in the &lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;original post&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The voice: BetterWispr
&lt;/h2&gt;

&lt;p&gt;I type less and talk more every day. With a team of agents, much of the work is explaining what I want and what's wrong. Talking, I explain it faster and in more detail than typing.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://betterwispr.com/" rel="noopener noreferrer"&gt;BetterWispr&lt;/a&gt;, which is open source and free. I dictate to the agent and the transcription comes out very well. macOS dictation already works, but adding the Parakeet Ultra model, about 730 MB, makes the result much better. It's absolutely worth it, and it barely uses any of the Mac's resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqot4paxzytkkfx0yssq3.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqot4paxzytkkfx0yssq3.webp" alt="The BetterWispr logo next to its name, its tagline Speak it messy. Send it clean., and the pill it shows while you dictate, with the voice waveform between the cancel and confirm buttons" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The knowledge: Obsidian
&lt;/h2&gt;

&lt;p&gt;The agents remember with Engram, but I need to remember too. &lt;a href="https://obsidian.md" rel="noopener noreferrer"&gt;Obsidian&lt;/a&gt; is my second brain: ideas, projects, and resources in one place.&lt;/p&gt;

&lt;p&gt;I organize it with two of Tiago Forte's frameworks. PARA defines where everything goes: Projects, Areas, Resources, and Archive, plus an Inbox at the entrance. CODE defines the flow: capture, organize, distill, and express.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjw529a8e0htidwz3ouv8.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjw529a8e0htidwz3ouv8.webp" alt="My vault in Obsidian: the folders 00 Inbox, 01 Projects, 02 Areas, 03 Resources, and 04 Archive, with the AGENTS note open, the contract the agents read, covering CODE and PARA" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The agents work with it both ways: they read it and they write to it, so the second brain stays up to date without me copying everything over by hand.&lt;/p&gt;

&lt;p&gt;Netty started there too, as one more note in the Inbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Netty, end to end
&lt;/h2&gt;

&lt;p&gt;This is how all the pieces came together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flicjic0q9emcnn2y40yz.webp" alt="Netty end to end in 41 seconds: a sentence from idea.md goes through three agents in herdr, 38 commits on October 27, the landing page checked in ego-browser, and the launch post, all the way to Netty's green dot" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Video in the &lt;a href="https://www.alvaldes.dev/blog/my-ai-dev-stack/" rel="noopener noreferrer"&gt;original post&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The context.&lt;/strong&gt; I started by giving the agent references to similar apps that already existed, so it knew the ground we'd be working on. Then I handed it my &lt;code&gt;idea.md&lt;/code&gt;, the file with all my notes on what I wanted to build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The app.&lt;/strong&gt; We went feature by feature. Whenever there was a result I could review, I reviewed it, corrected what was needed, and we moved on to the next one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The design.&lt;/strong&gt; I gave it references for the style I wanted. The agent opened them in ego-browser, studied them, and brought those styles into the app. I kept reviewing along the way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The website.&lt;/strong&gt; In its own worktree, another agent built the landing page element by element and published it on &lt;a href="https://alvaldes.github.io/netty/" rel="noopener noreferrer"&gt;GitHub Pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The launch.&lt;/strong&gt; I did all of it with &lt;a href="https://www.alvaldes.dev/blog/launch-skills/" rel="noopener noreferrer"&gt;launch-skills&lt;/a&gt;, my open-source skills for launching projects, and ego-browser. The agent prepared the kit, generated the images, filled in the directory forms, and drafted the posts for each network. Before each one went out, it stopped and showed me what it was about to send. The last click was always mine.&lt;/p&gt;

&lt;h2&gt;
  
  
  An extra: the team in your pocket
&lt;/h2&gt;

&lt;p&gt;The stack works without this, but this takes it further.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tailscale.com" rel="noopener noreferrer"&gt;Tailscale&lt;/a&gt; connects the Mac and the phone in a private network. As long as the Mac is on and online, I can reach herdr from my phone, anywhere, and keep talking to the agents without carrying the computer.&lt;/p&gt;

&lt;p&gt;On the iPhone side I use &lt;a href="https://getmoshi.app/" rel="noopener noreferrer"&gt;Moshi&lt;/a&gt;, though other terminal clients such as &lt;a href="https://termius.com/" rel="noopener noreferrer"&gt;Termius&lt;/a&gt; work too.&lt;/p&gt;

&lt;p&gt;It happened to me many times with Netty. An agent got stuck, told me what was blocking it, and I unblocked it from my phone so it could keep working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed, and what didn't
&lt;/h2&gt;

&lt;p&gt;Netty went from a note in the Inbox to a published app in four days, and I barely wrote any of the code.&lt;/p&gt;

&lt;p&gt;My job is different now. I decide what gets built and in what order. I give each agent the context it needs, from the references to what I learned on JUMP. I review every result before moving on and correct it when it isn't right. I'm a project manager with a team, not a developer with autocomplete.&lt;/p&gt;

&lt;p&gt;What didn't change is that someone has to know whether the work is good. An agent is wrong with the same confidence it's right. The tools in this post don't remove that review: they organize it. Worktrees keep the agents from stepping on each other, and ego-browser lets me see every page before I approve it. The last word is still mine.&lt;/p&gt;

&lt;p&gt;The agents execute. I direct.&lt;/p&gt;

&lt;p&gt;If you want to build something similar, everything in this post is public: my configuration is in &lt;a href="https://github.com/alvaldes/alvaldes.dots" rel="noopener noreferrer"&gt;alvaldes.dots&lt;/a&gt;, each tool is linked in its section, and &lt;a href="https://github.com/alvaldes/netty" rel="noopener noreferrer"&gt;Netty&lt;/a&gt; is open source. And if you work differently, I'd like to hear about it: &lt;a href="https://www.alvaldes.dev/#contact-me" rel="noopener noreferrer"&gt;write to me&lt;/a&gt; and tell me about your stack.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Netty: is the internet really there?</title>
      <dc:creator>Angel L. Valdés</dc:creator>
      <pubDate>Sat, 31 Oct 2026 19:57:55 +0000</pubDate>
      <link>https://dev.to/alvaldesdev/netty-is-the-internet-really-there-5g1k</link>
      <guid>https://dev.to/alvaldesdev/netty-is-the-internet-really-there-5g1k</guid>
      <description>&lt;p&gt;The Wi-Fi icon in the menu bar answers one question: am I connected to a network? It doesn't tell you whether the internet actually answers. A hotel login page, a router that lost its uplink or a connection that crawls all look the same: full bars.&lt;/p&gt;

&lt;p&gt;I wanted a dot that answers the question that matters. Am I really online? Is the connection good? How fast is it?&lt;/p&gt;

&lt;p&gt;That's &lt;a href="https://alvaldes.github.io/netty/" rel="noopener noreferrer"&gt;Netty&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;Netty is a macOS menu bar app. Its icon is a dot that changes color with your connection:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Color&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;When&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Green&lt;/td&gt;
&lt;td&gt;Online&lt;/td&gt;
&lt;td&gt;The internet answers and the connection is good.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Yellow&lt;/td&gt;
&lt;td&gt;Degraded&lt;/td&gt;
&lt;td&gt;Latency, jitter or packet loss crosses a threshold.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Red&lt;/td&gt;
&lt;td&gt;Offline&lt;/td&gt;
&lt;td&gt;A few checks in a row failed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Click the dot and a popover shows latency, jitter, loss, the last speed test and your network: Wi-Fi name, Ethernet or hotspot, whether a VPN carries your traffic, and your local and public IP. You get a notification when the connection drops and when it comes back, with how long you were offline.&lt;/p&gt;

&lt;p&gt;Almost everything can be changed: the rules for yellow and red, which sections the popover shows and in what order, what each click does, and the icon itself, in color or black and white, with SF Symbols or your own image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx3rd70ai26h85xgolzsf.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx3rd70ai26h85xgolzsf.webp" alt="Netty's settings: show, hide and reorder the popover's sections with a live preview" width="799" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built my own
&lt;/h2&gt;

&lt;p&gt;There are good apps that do this, like &lt;a href="https://netbar.xyz/" rel="noopener noreferrer"&gt;Netbar&lt;/a&gt; and &lt;a href="https://netdot.app/" rel="noopener noreferrer"&gt;Netdot&lt;/a&gt;, and &lt;a href="https://sindresorhus.com/online-check" rel="noopener noreferrer"&gt;Online Check&lt;/a&gt; does the "real internet" part well. I used them as references. But I wanted one that was free, open source and designed with the same care as the rest of macOS. Netty ships under GPL-3.0, like &lt;a href="https://www.alvaldes.dev/en/blog/introducing-jump/" rel="noopener noreferrer"&gt;JUMP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works under the hood
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Real internet, not just a network.&lt;/strong&gt; Netty asks Apple's captive portal check, with Google's as a fallback, whether the internet answers. Wi-Fi without internet or a login page counts as offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quality from a TCP handshake.&lt;/strong&gt; Every 10 seconds Netty opens a TCP connection to 1.1.1.1 and 8.8.8.8 and times the handshake. Latency, jitter and loss come from those samples. It also checks right away when the network changes or when you click the icon, so a drop or a recovery is confirmed at once instead of waiting for the next interval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed with the tool macOS already has.&lt;/strong&gt; The speed test uses Apple's built-in &lt;code&gt;networkQuality&lt;/code&gt;: download, upload and responsiveness. No servers of my own. It runs when you ask, or on a schedule that's off by default and skips metered networks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nothing leaves your Mac.&lt;/strong&gt; No analytics, no telemetry. The checks go to Apple, Google and Cloudflare, and the public IP is looked up only when you open the popover, at most every 5 minutes. Hide it and it's never looked up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The core is its own package.&lt;/strong&gt; The rules that turn probe samples into a status live in &lt;code&gt;NettyKit&lt;/code&gt;, a Swift package that's tested without opening the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swift &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--package-path&lt;/span&gt; Packages/NettyKit
&lt;span class="nv"&gt;NETTY_LIVE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 swift &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--package-path&lt;/span&gt; Packages/NettyKit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second command also hits the real network and runs a speed test. Keeping it behind a flag means the normal suite is fast and doesn't depend on your connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reviewing the UI without opening it.&lt;/strong&gt; Debug builds can render the popover, every Settings pane and every icon to PNG files and quit. I check a change in light and dark, in each status, without clicking through the app. The screenshots in this post came out of that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Wi-Fi name needs Location.&lt;/strong&gt; macOS only shares the network name with apps that have Location access. Netty asks for it with its reason, never reads your location, and still works if you say no: it just shows "Wi-Fi".&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Netty needs macOS 26 or later. Download it from &lt;a href="https://alvaldes.github.io/netty/" rel="noopener noreferrer"&gt;its website&lt;/a&gt; or from &lt;a href="https://github.com/alvaldes/netty" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, or install it with Homebrew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--cask&lt;/span&gt; alvaldes/tap/netty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;It isn't notarized by Apple yet, so macOS blocks it the first time. &lt;a href="https://www.alvaldes.dev/en/blog/open-unnotarized-mac-apps/" rel="noopener noreferrer"&gt;This guide&lt;/a&gt; walks you through opening it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If something breaks, or you have an idea to make it better, &lt;a href="https://github.com/alvaldes/netty/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt; in the repository.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.alvaldes.dev/en/blog/introducing-netty/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>macos</category>
      <category>swift</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>JUMP: keyboard-first, even outside the browser</title>
      <dc:creator>Angel L. Valdés</dc:creator>
      <pubDate>Wed, 28 Oct 2026 18:22:25 +0000</pubDate>
      <link>https://dev.to/alvaldesdev/jump-keyboard-first-even-outside-the-browser-22km</link>
      <guid>https://dev.to/alvaldesdev/jump-keyboard-first-even-outside-the-browser-22km</guid>
      <description>&lt;p&gt;In the browser I barely touch the mouse. I use &lt;a href="https://github.com/brookhong/Surfingkeys" rel="noopener noreferrer"&gt;Surfingkeys&lt;/a&gt;, an extension that puts a label on every link and button: I type the label and that's the click. Over the years I built my whole setup around the keyboard, and Vim's &lt;code&gt;h j k l&lt;/code&gt; keys are muscle memory by now.&lt;/p&gt;

&lt;p&gt;The trouble started when I left the browser. To click a single button in Finder, System Settings or any other app, I had to let go of the keyboard, reach for the mouse and come back. A few milliseconds, sure. But it happens many times a day and it adds up, and I'm a productivity nerd: those milliseconds matter to me.&lt;/p&gt;

&lt;p&gt;That's where &lt;a href="https://alvaldes.github.io/jump/" rel="noopener noreferrer"&gt;JUMP&lt;/a&gt; came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;JUMP is a macOS menu bar app. Press a shortcut and every clickable element in the focused window gets a short label. Type the label and JUMP clicks it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shortcut&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
⌘ ⇧ Space
&lt;/td&gt;
&lt;td&gt;Hints&lt;/td&gt;
&lt;td&gt;Labels every clickable element. Type a label to click it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
⌘ ⇧ J
&lt;/td&gt;
&lt;td&gt;Scroll&lt;/td&gt;
&lt;td&gt;Scrolls the window Vim-style: &lt;code&gt;h j k l&lt;/code&gt;, &lt;code&gt;d u&lt;/code&gt;, &lt;code&gt;gg G&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
⌘ ⇧ F
&lt;/td&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;Finds visible text, ignoring case and accents.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Hold a modifier while typing the label to pick the action: ⇧ right-clicks, ⌘ double-clicks and ⌥ only moves the pointer. All three shortcuts and the modifiers can be changed in Settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsexl1xpn049brwc4ihcl.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsexl1xpn049brwc4ihcl.webp" alt="JUMP's settings: how the labels look and how clicks behave" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I didn't use something that already existed
&lt;/h2&gt;

&lt;p&gt;The first thing I did was look around. I found two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/nchudleigh/vimac" rel="noopener noreferrer"&gt;Vimac&lt;/a&gt;, open source, but untouched since December 2022.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.homerow.app" rel="noopener noreferrer"&gt;Homerow&lt;/a&gt;, its commercial successor: it works well, but it's paid and closed source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither felt right, so I thought: why not build my own tool, the way I like it, free and open source? I'm an open-source fan. I like the community that grows around a project and the idea of sharing what you learn. JUMP starts from Vimac's code, which is GPL-3.0, modernizes it for macOS 26 and ships under the same license.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works under the hood
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Accessibility API.&lt;/strong&gt; macOS exposes every app's interface as a tree of elements: buttons, fields, links. JUMP walks that tree in the focused window, keeps what can be acted on and draws the labels on top. That's why it needs the Accessibility permission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OCR as a fallback.&lt;/strong&gt; Some windows don't expose their text through Accessibility, like terminals or PDFs. For those, JUMP can recognize the text on screen with the Vision framework. It's off by default, asks for the Screen Recording permission only when you turn it on, and the captures never leave memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No Mac App Store.&lt;/strong&gt; Store apps run in a sandbox, and an app that reads and drives other apps through Accessibility can't work from inside one. JUMP ships through GitHub Releases instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Engineering decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The core is its own package.&lt;/strong&gt; The logic lives in &lt;code&gt;JumpKit&lt;/code&gt;, a Swift package that's tested without opening the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swift &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--package-path&lt;/span&gt; Packages/JumpKit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing something that depends on other windows and system permissions is hard. Keeping the core apart from the UI makes it testable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The permission that vanished on every build.&lt;/strong&gt; macOS ties the Accessibility permission to the app's code signature. With the default ad-hoc signature, the signature changes on every build and the permission is gone. The fix was signing with my own development certificate, and the release script refuses to publish an ad-hoc signed app: users would lose the permission on every update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A release you can't get wrong.&lt;/strong&gt; The same script also rejects uncommitted changes and untagged commits. I'd rather it fail than ship something I can't reproduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;JUMP needs macOS 26 or later. Download it from &lt;a href="https://alvaldes.github.io/jump/" rel="noopener noreferrer"&gt;its website&lt;/a&gt; or from &lt;a href="https://github.com/alvaldes/jump" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It isn't notarized by Apple yet, so macOS blocks it the first time. The &lt;a href="https://github.com/alvaldes/jump#install" rel="noopener noreferrer"&gt;README&lt;/a&gt; walks you through opening it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you use it and something breaks, or you have an idea to make it better, &lt;a href="https://github.com/alvaldes/jump/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt; in the repository. That's what open source is for.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.alvaldes.dev/en/blog/introducing-jump/" rel="noopener noreferrer"&gt;my blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>macos</category>
      <category>opensource</category>
      <category>swift</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
