My Agentic Journey, So Far
Finding my way back to Neovim, tmux, and OpenCode.
Over the last few years, AI and agents have taken me on quite the journey. My first introduction to AI was through the browser ChatGPT interface. It was essentially a replacement for Google, with hallucinations, but it often helped me find answers a tiny bit quicker than scrolling Stack Overflow or sifting through GitHub issues. I still found myself doing some manual Googling from time to time because the answers were sometimes straight-up bad.
Starting In VS Code
As a long-time user of Neovim, I longed for the terminal. I wanted a place to work with AI while staying in the environment where I was writing my code. It was around this time that Claude Code came out, but there was an issue: I worked at a cybersecurity company that was a Microsoft shop. Because of that, GitHub Copilot was the only agent we were allowed to use. Not the CLI, just the agent built into VS Code. We couldn’t use Cursor, Zed, or any other editor. Honestly, I probably shouldn’t have been using Neovim. So I had to make the switch to VS Code.
An obvious first step was enabling Vim mode. That didn’t help the experience much, though. Everything felt clunky, but I did what I had to do to work with Copilot. The models of choice at this time were GPT-4.0 and Claude Sonnet 3.5.
My main workflow was to find boring, rudimentary tasks for the agent to do across the codebase. A good example was anything slightly more complicated than search and replace, like updating usages of mock data whenever the API contract changed.
Like many big companies, we used OpenAPI specs to help keep things maintainable. With any change to the spec came changes to the TypeScript types. We generated mock data based on those types, then used that mock data in tests to assert loading states, error states, empty states, success states, and so on. Anytime the data changed, we had to go through the tedious task of finding every instance of that mock and ensuring it was updated.
A quick prompt like this started to feel useful:
Find all instances of this mocked data structure by running
tsc. Fix any failures intscrelated to mock data. When you are done, make a new PR for ticket 1234.
This is where working with AI started to become fun. But keep in mind, at this point, in my opinion, it still couldn’t really think. You couldn’t give it complex problems and expect it to come up with great solutions.
This is how I worked for a long time: some refactors here, sweeping bulk updates there, updating function docs, READMEs, and so on.
Discovering Better Diffs
Fast-forward to the start of 2026. It wasn’t until I started a new job and, coincidentally, GPT-5.3 Codex came out that my entire workflow changed. Now working at a startup called Collaborative Robotics, I had the freedom to use the tools I wanted: Neovim, tmux, and OpenCode. Editor on the left, OpenCode on the right.
I could finally flow on the keyboard, but there was a problem: diffs. I found myself wanting an easier way to look at the diffs of the changes the agent was making. OpenCode did a decent job showing them inline in the chat, but this was cumbersome, especially on a laptop where two-thirds of the screen was the editor.
Diffs are the key to being effective with agents. If we want to build higher-quality software, we need a quality diffing tool. The problem was that, at this point, I didn’t know what that looked like.
Then I stumbled on opencode serve, a command that serves the OpenCode desktop locally on whatever port you want.
Living In OpenCode Desktop
This workflow was fundamentally different from what I was used to. There was no editor, just a pane for the agent chat, a pane for the diff of changes, and a small file explorer. I quickly went from manually typing 50% of my code to the agent typing 100% of it. It was magical.
The diff tool was unreal. I could click on a line, leave a comment for a change I wanted made, and that comment would be automatically added as context in my next message to the agent. Off we went. I was burning tokens for the smallest changes.
The feature I absolutely loved was called “Last turn changes”. It allowed you to view only the changes the agent made from your most recent message. That meant I could quickly go through the diff and leave comments on just those changes without being bombarded by every other change on the branch. Of course, you could still view the branch diff as well.
I worked like this for a couple of months, and honestly, I found myself fully reliant on the agent and OpenCode. When I ran out of GPT tokens, using Claude felt cumbersome because it was no longer available in OpenCode. Not only that, but I kept feeling further and further away from the code. I was quickly losing my bearings in the codebase and feeling this deep sense of lost control. I felt like if the agent disappeared, I would be almost incapable of picking up where it left off.
Now, I am sure many people have felt this way, and many others would argue that this is the future: outcomes are the only thing that matters, not the code. If I am being logical, I fully agree. But something inside me prevents me from releasing control over the code and being okay with never looking at it again.
I take tremendous pride in the work I do, and I also love to learn. FWIW, I am skeptical of people who say they are learning more than ever with AI. Are you really retaining all that new “knowledge” that has been streamed to you via tokens in a text chat? Maybe at a high level, but if the agents disappeared tomorrow, do you think you could pick up where they left off?
Back To Neovim
All of this brings me to where I am today: back to my roots in Neovim, tmux, and OpenCode in the terminal. I took all of my favorite features from OpenCode desktop and tried to replace them with plugins and keymaps in Neovim.
Diffs are rendered using sindrets/diffview.nvim. I have two keymaps:
leader ggopens the current diff since the last commit.leader gbopens the diff of the whole branch.
Then I have another keymap to replicate the “comment on a line” workflow: leader yr in visual mode. It lets me select a chunk of code and copy the absolute path to the file, including the selected line numbers. This gives the agent a surgical prompt for where to make changes.
The keymaps look like this:
-- Diffview shortcuts for reviewing agent changes.keys = { { "<leader>gg", "<cmd>DiffviewOpen<cr>", desc = "open git diff view" }, { "<leader>gb", "<cmd>DiffviewOpen origin/main...HEAD --imply-local<cr>", desc = "branch diff against main" }, { "<leader>gG", "<cmd>DiffviewClose<cr>", desc = "close git diff view" },}
-- Copy a precise file reference for the selected lines.vim.keymap.set("x", "<leader>yr", function() local start_pos = vim.fn.getpos("v") local end_pos = vim.fn.getpos(".") local start_line = math.min(start_pos[2], end_pos[2]) local end_line = math.max(start_pos[2], end_pos[2]) local path = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(0), ":~:.") local ref = start_line == end_line and string.format("%s:%d", path, start_line) or string.format("%s:%d-%d", path, start_line, end_line)
vim.fn.setreg("+", ref) vim.notify("Copied: " .. ref)end, { desc = "copy file path and selected line range" })OpenCode has its own window in tmux. I primarily work on my laptop, so I need more horizontal space for the diff view.
I also have a couple of OpenCode commands that smooth out the branch workflow:
/pushcommits and pushes all changes on the current branch./prcommits and pushes the branch, then creates a PR for the ticket or context I pass in, using the repo’s commit guide for the commit message, PR title, and PR description.
They are tiny commands, but that is why I like them. They turn the administrative end of a change into muscle memory, while still keeping the implementation and review loop in my editor.
Given what I mentioned before about being closer to the code, this may seem like I am no closer. But I am. I am working in my editor of choice, and at any point I can start making changes manually without needing the agent. The workflow doesn’t get in my way. It actually makes things easier because when I run out of GPT tokens now, I just fire up Claude and keep working. Nothing else changes.
For now, this is working well, and I’ll continue to work this way until I find I can no longer keep up. What I am learning through all of this is that it is okay to just SLOWWWWWW down. I am writing this as a reminder to myself, having recently been burnt out.
Maybe that is the balance I have been looking for: letting the agents help, without letting them take me too far away from the work.