<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://tolexx.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://tolexx.dev/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-10-22T18:45:14+00:00</updated><id>https://tolexx.dev/feed.xml</id><title type="html">Tochukwu Uzochukwu</title><subtitle>Programmer. I keep web applications healthy, make test suites fast, and write about tools and working with AI coding agents.</subtitle><author><name>Tochukwu Uzochukwu</name><email>tochukwu@tolexx.dev</email></author><entry><title type="html">Why I switched from VScode to herdr</title><link href="https://tolexx.dev/2026/10/22/why-i-switched-from-vscode-to-herdr.html" rel="alternate" type="text/html" title="Why I switched from VScode to herdr" /><published>2026-10-22T00:00:00+00:00</published><updated>2026-10-22T00:00:00+00:00</updated><id>https://tolexx.dev/2026/10/22/why-i-switched-from-vscode-to-herdr</id><content type="html" xml:base="https://tolexx.dev/2026/10/22/why-i-switched-from-vscode-to-herdr.html"><![CDATA[<p>A while back I wrote about <a href="/2024/02/19/how-to-setup-helix-editor-for-ruby.html">setting up Helix for Ruby</a>.
In that post I said I was a longtime VScode user and still liked it. That stayed
true for a long time after. Helix was something I played with, but VScode was
where I did my actual work.</p>

<p>Recently I installed <a href="https://github.com/herdrdev/herdr">herdr</a>, and since then
VScode has not been my main setup. This post is about why I made the
switch and what I use now.</p>

<h2 id="i-stopped-writing-most-of-my-code-by-hand">I stopped writing most of my code by hand</h2>

<p>The biggest change was not the tool. It was the way I work. These days AI coding
agents write most of the code, and my job is mostly to read it. I review what they
changed, follow a method to where it is defined, check where something is used,
and decide whether the change is right.</p>

<p>VScode is built around writing code, and for what I was doing it started to feel
heavy. It is also hungry for memory. Out of curiosity I measured it on the Rails
app I am working on right now. With one VScode window open, VScode was using about
<strong>1.2 GB</strong> of memory spread over 20 processes. That number includes my extensions
and the language servers they start.</p>

<p>My current setup on the same machine: two TTT editor instances use about <strong>50 MB</strong>
together, and herdr itself, the server and its clients, uses about <strong>40 MB</strong>. (These are
PSS numbers, which count shared memory only once. TTT’s number does not include
<code class="language-plaintext highlighter-rouge">ruby-lsp</code>, which runs as its own process.)</p>

<p>So I wanted something lighter that is built for reading code and keeping an eye on
agents, not for typing all day.</p>

<h2 id="herdr">herdr</h2>

<p>herdr describes itself as a “terminal workspace manager for AI coding agents”. If
you have used tmux, some of it will feel familiar: you get workspaces, tabs and split
panes in your terminal. The difference is that herdr knows about the agents running
inside those panes.</p>

<p>These are the parts that matter to me:</p>

<ul>
  <li><strong>One workspace per project.</strong> I have a workspace for each project I am working on,
and each one keeps its own tabs and layout.</li>
  <li><strong>Agent status.</strong> The sidebar shows whether each agent is working, blocked, done
or idle, across every workspace. When an agent is waiting on me, I can see it
without hunting through tabs.</li>
  <li><strong>Things keep running.</strong> herdr runs your panes in a background server. I can
detach with <code class="language-plaintext highlighter-rouge">ctrl+b q</code>, and the panes and agents keep running. Running <code class="language-plaintext highlighter-rouge">herdr</code>
again puts me back where I was. I also use named sessions, so
<code class="language-plaintext highlighter-rouge">herdr session attach hobby</code> takes me to my side projects. Each named session
runs as its own herdr server.</li>
  <li><strong>It is scriptable.</strong> There is a CLI for almost everything, like <code class="language-plaintext highlighter-rouge">herdr pane split</code>,
<code class="language-plaintext highlighter-rouge">herdr agent start</code> and <code class="language-plaintext highlighter-rouge">herdr tab create</code>. The commands return JSON, so a bit of
shell and <code class="language-plaintext highlighter-rouge">jq</code> goes a long way.</li>
</ul>

<h2 id="ttt-for-reading-code">TTT for reading code</h2>

<p>For the editor I use <a href="https://github.com/eugenioenko/ttt">TTT</a> (Terminal Text Tool).
It describes itself as “the IDE that lives in your terminal”, and it is a single Go
binary. It also comes with a herdr plugin, which is how I installed it.</p>

<p>What sold me is its LSP support, which is exactly what you need when you read more
code than you write. TTT ships with configurations for 25 language servers. You
install the server, and TTT picks it up. For Ruby that is <code class="language-plaintext highlighter-rouge">ruby-lsp</code>. With it I get
go to definition (<code class="language-plaintext highlighter-rouge">F12</code>), find all references (<code class="language-plaintext highlighter-rouge">Ctrl+L R</code>), hover documentation
(<code class="language-plaintext highlighter-rouge">Ctrl+K I</code>), and diagnostics shown inline.</p>

<p>TTT also has Git built in. The changes panel lets you stage, unstage, discard and
commit, and it opens a diff for any changed file, either side by side or unified.
That is where I review what an agent did. It is also a little funny, because at the
end of my Helix post I said I was still looking forward to proper Git integration.
I got it in the end, just in a different editor.</p>

<h2 id="my-setup">My setup</h2>

<p>Here is a short recording of my setup.</p>

<video src="/assets/images/herdr-setup.mp4" poster="/assets/images/herdr-setup.jpg" controls="" muted="" loop="" playsinline="" style="max-width: 100%;"></video>

<p>TTT is on the left. On the right are two Claude Code panes and an opencode pane. In
the recording I open my Helix post in TTT and ask one of the Claude panes a question
about the blog. Then I create a second workspace for another repository. Its layout
builds in the background, and you can see its Claude panes show up as blocked in
the sidebar, because they are waiting for me to trust the folder.</p>

<h3 id="a-plugin-for-the-layout">A plugin for the layout</h3>

<p>I use this same layout for almost every project, so I wrote a small local herdr
plugin for it. A plugin is a manifest plus a script. This is part of the manifest:</p>

<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">id</span> <span class="p">=</span> <span class="s">"tolexx.dev-layout"</span>
<span class="py">name</span> <span class="p">=</span> <span class="s">"Dev Layout"</span>
<span class="py">version</span> <span class="p">=</span> <span class="s">"0.1.0"</span>
<span class="py">min_herdr_version</span> <span class="p">=</span> <span class="s">"0.9.0"</span>
<span class="py">description</span> <span class="p">=</span> <span class="s">"ttt on the left; claude, claude and opencode stacked on the right"</span>
<span class="py">platforms</span> <span class="p">=</span> <span class="p">[</span><span class="s">"linux"</span><span class="p">,</span> <span class="s">"macos"</span><span class="p">]</span>

<span class="nn">[[actions]]</span>
<span class="py">id</span> <span class="p">=</span> <span class="s">"apply"</span>
<span class="py">title</span> <span class="p">=</span> <span class="s">"Apply dev layout"</span>
<span class="py">contexts</span> <span class="p">=</span> <span class="nn">["workspace"]</span>
<span class="py">command</span> <span class="p">=</span> <span class="p">[</span><span class="s">"sh"</span><span class="p">,</span> <span class="s">"layout.sh"</span><span class="p">,</span> <span class="s">"apply"</span><span class="p">]</span>
</code></pre></div></div>

<p>and the part I like the most:</p>

<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[[events]]</span>
<span class="py">on</span> <span class="p">=</span> <span class="s">"workspace.created"</span>
<span class="py">command</span> <span class="p">=</span> <span class="p">[</span><span class="s">"sh"</span><span class="p">,</span> <span class="s">"layout.sh"</span><span class="p">,</span> <span class="s">"auto"</span><span class="p">]</span>
</code></pre></div></div>

<p>When I create a new workspace inside a Git repository, the script splits the panes,
runs <code class="language-plaintext highlighter-rouge">ttt .</code> on the left, and starts the agents on the right with <code class="language-plaintext highlighter-rouge">herdr agent start</code>.
I don’t have to do anything.</p>

<h3 id="keybindings">Keybindings</h3>

<p>The rest lives in <code class="language-plaintext highlighter-rouge">~/.config/herdr/config.toml</code>. These are some of my bindings:</p>

<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[[keys.command]]</span>
<span class="py">key</span> <span class="p">=</span> <span class="s">"prefix+d"</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">"plugin_action"</span>
<span class="py">command</span> <span class="p">=</span> <span class="s">"tolexx.dev-layout.apply"</span>
<span class="py">description</span> <span class="p">=</span> <span class="s">"dev layout: ttt + 2 claude + opencode"</span>

<span class="nn">[[keys.command]]</span>
<span class="py">key</span> <span class="p">=</span> <span class="s">"prefix+a"</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">"plugin_action"</span>
<span class="py">command</span> <span class="p">=</span> <span class="s">"tolexx.dev-layout.spawn-claude"</span>
<span class="py">description</span> <span class="p">=</span> <span class="s">"spawn claude below focused pane"</span>

<span class="nn">[[keys.command]]</span>
<span class="py">key</span> <span class="p">=</span> <span class="s">"prefix+f"</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">"popup"</span>
<span class="py">command</span> <span class="p">=</span> <span class="s">"exec </span><span class="se">\"</span><span class="s">${SHELL:-sh}</span><span class="se">\"</span><span class="s">"</span>
<span class="py">description</span> <span class="p">=</span> <span class="s">"floating scratch shell"</span>
<span class="py">width</span> <span class="p">=</span> <span class="s">"80%"</span>
<span class="py">height</span> <span class="p">=</span> <span class="s">"80%"</span>

<span class="nn">[[keys.command]]</span>
<span class="py">key</span> <span class="p">=</span> <span class="s">"prefix+shift+a"</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">"pane"</span>
<span class="py">command</span> <span class="p">=</span> <span class="s">"claude"</span>
<span class="py">description</span> <span class="p">=</span> <span class="s">"zoomed throwaway claude (closes on exit)"</span>
</code></pre></div></div>

<p>The floating shell and the throwaway Claude pane are for quick one-off things. The
shell opens as a popup without changing my layout. The Claude pane opens zoomed and
closes by itself when I exit Claude.</p>

<h2 id="what-is-not-perfect">What is not perfect</h2>

<p>herdr is young. I installed version 0.9.3, and there have been two releases since
then, one of them a hotfix. Since June there has been a new stable release about
every week or two. Nothing has broken for me so far, but expect rough edges.</p>

<p>There is also a learning curve. VScode is still more beginner-friendly, and I would
still recommend it to someone just starting out. With herdr you will spend time in
the docs and the <code class="language-plaintext highlighter-rouge">--help</code> output. To get the most out of it, you will write a bit
of shell.</p>

<p>I also have not uninstalled VScode. I still open it now and then, mostly to look at
a Markdown file. It is just not where I spend my day anymore.</p>

<h2 id="conclusion">Conclusion</h2>

<p>My experience so far has been good. My work has moved from writing code to reading
it and managing the agents that write it, and herdr with TTT fits that much better
than VScode did. It also uses a lot less memory. If your days look like mine, I
think it is worth a try.</p>]]></content><author><name>Tochukwu Uzochukwu</name><email>tochukwu@tolexx.dev</email></author><summary type="html"><![CDATA[Why I moved my day-to-day work from VScode to herdr and TTT, now that I read more code than I write.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://tolexx.dev/assets/images/herdr-setup.jpg" /><media:content medium="image" url="https://tolexx.dev/assets/images/herdr-setup.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to setup helix editor for ruby</title><link href="https://tolexx.dev/2024/02/19/how-to-setup-helix-editor-for-ruby.html" rel="alternate" type="text/html" title="How to setup helix editor for ruby" /><published>2024-02-19T00:00:00+00:00</published><updated>2024-02-19T00:00:00+00:00</updated><id>https://tolexx.dev/2024/02/19/how-to-setup-helix-editor-for-ruby</id><content type="html" xml:base="https://tolexx.dev/2024/02/19/how-to-setup-helix-editor-for-ruby.html"><![CDATA[<p>I have been a longtime VScode user, and I still like it. It is very
beginner-friendly. It’s pretty much a plug-and-play editor as it has many extensions
for most tasks you want to perform, requiring very little configuration on your part.
Additionally, it has a large community around it.</p>

<p>For a long time, I have always wanted to try out a terminal editor - something
really light and simple. In my quest to find one that I resonate with, I spent time
researching on so many lightweight terminal editors. They include:</p>

<ul>
  <li>Vim</li>
  <li>Emacs</li>
  <li>Kakoune</li>
  <li>Helix</li>
  <li>Neovim</li>
  <li>Lapce</li>
  <li>Litexl</li>
  <li>Microedit</li>
</ul>

<p>In the end, I had to settle for Helix. <a href="https://helix-editor.com/">Helix</a> is a lightweight editor written in Rust.
It draws inspiration from the Kakoune editor and it’s opensource too. I opted for
Helix because it’s fairly easy to learn compared to Vim, Emacs or even Neovim.
It has several things set up for you upfront and, its LSP support is quite good.</p>

<p>I currently work professionally with Ruby and develop web applications with Ruby on Rails.
I’ll share how I was able to setup a fairly simple configuration for developing in
Ruby with Helix. Most of your configurations will be in the <code class="language-plaintext highlighter-rouge">languages.toml</code> file
for language-specific configurations and <code class="language-plaintext highlighter-rouge">config.toml</code> file for editor-specific
configurations. You will need the following libraries installed on your computer:</p>

<ul>
  <li><a href="https://solargraph.org/">Solargraph</a>: This provides IntelliSense and autocomplete functionality</li>
  <li><a href="https://github.com/estin/simple-completion-language-server">Completion Language Server</a>: This
is a Rust library and will require Cargo installed. Essentially, it’s a snippets
library that provides autocompletion. You can read the README for installation guidelines.</li>
</ul>

<p>My experience with the editor so far has been decent. It’s not perfect yet, but it’s 
good enough. I am still looking forward to proper integration with Git. Check <a href="https://github.com/4tolexx/helix-editor-config">config</a>
for configuration ideas. It is also worth reading the official documentation of
Helix Editor for learning key bindings and other configurations.</p>]]></content><author><name>Tochukwu Uzochukwu</name><email>tochukwu@tolexx.dev</email></author><summary type="html"><![CDATA[A simple Helix editor setup for Ruby, with Solargraph for autocomplete and a snippets language server.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://tolexx.dev/assets/images/og-default.png" /><media:content medium="image" url="https://tolexx.dev/assets/images/og-default.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to modify an old commit</title><link href="https://tolexx.dev/2024/01/29/modify-an-old-commit.html" rel="alternate" type="text/html" title="How to modify an old commit" /><published>2024-01-29T00:00:00+00:00</published><updated>2024-01-29T00:00:00+00:00</updated><id>https://tolexx.dev/2024/01/29/modify-an-old-commit</id><content type="html" xml:base="https://tolexx.dev/2024/01/29/modify-an-old-commit.html"><![CDATA[<p>There are times when you may have an existing commit, but you have just made changes to a file or a couple of files. Perhaps you don’t want to create a new commit, but you would rather modify the old commit and add your changes to it. Below are the Git commands I use in such cases.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add &lt; changed files <span class="o">&gt;</span>
git commit <span class="nt">--fixup</span><span class="o">=</span>&lt;OLDCOMMIT sha-value&gt;
git rebase <span class="nt">--interactive</span> <span class="nt">--autosquash</span> OLDCOMMIT^
</code></pre></div></div>

<p><strong>explanation</strong></p>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">git commit --fixup=&lt;OLDCOMMIT sha-value&gt;</code>: This command takes the message of the OLDCOMMIT and automatically apply <code class="language-plaintext highlighter-rouge">fixup!</code> to it which is similar to when you run an interactive rebase and you apply the <code class="language-plaintext highlighter-rouge">fixup</code> option.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">git rebase --interactive --autosquash OLDCOMMIT^</code>: The caret(^) symbol here refers to the parent commit of OLDCOMMIT. <code class="language-plaintext highlighter-rouge">--autosquash OLDCOMMIT</code> automatically puts any <code class="language-plaintext highlighter-rouge">--fixup=OLDCOMMIT</code> in the correct order. Note that –autosquash is only valid when the –interactive option is used.</p>
  </li>
</ul>]]></content><author><name>Tochukwu Uzochukwu</name><email>tochukwu@tolexx.dev</email></author><summary type="html"><![CDATA[Adding new changes to an older Git commit with git commit --fixup and an autosquash rebase.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://tolexx.dev/assets/images/og-default.png" /><media:content medium="image" url="https://tolexx.dev/assets/images/og-default.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>