Ubik Devlog #1
I’m working on something new called Ubik. It’s an issue tracker and code review tool that stores its data in your Git repository. It’s named after a Philip K. Dick novel. I might change the name, but it’s short and will do for now.
I’ve been working on it since February, but I was learning too many new concepts at once and massively overcomplicated things. Sometimes, it’s hard to remember to KISS. A couple of weeks ago, I decided to delete everything and start fresh. Here’s a quick demo.
Inspired by Mitchell Hashimoto’s Ghostty devlogs and with encouragement from DZ, I’m going to use this devlog to write about my progress. I’m aiming to put something out every couple of weeks. The writing will be light on rigor so I can stay consistent, but we’ll see how things evolve. If I’m wrong about something, please send me an email and I’ll gladly correct the record.
The tech stack
You may have watched the demo above and have been surprised that you’re not looking at a web app. Nor a native app. Everything is happening in my terminal emulator!
That’s made possible by Charm’s fantastic TUI (Terminal User Interface) libraries, which are written in Go. I wouldn’t have even considered building something like Ubik had I not discovered their work. Now that I had these new tools available to me, building in terminal felt like the right choice for the initial version of the UI for a few reasons:
- Many programmers are comfortable with using the basics of Git on the command line
- Source code is stored in a filesystem, not a relational database
- Terminals have direct access to your filesystem
Building an interface in the terminal is cool and all, but the interesting part is how Ubik leverages Git to store data. Git has a clever data model that allows one to store arbitrary things, not just source code, in its “database”. I’ll explain how this works in much more depth in a future devlog. There are some interesting trade-offs (e.g. the need for custom conflict resolution, no clear approach for tracking history) to my approach that I’m not done wrestling with. Here’s a little follow-along demo that outlines the way Ubik currently stores its data:
Navigate to a Git repository on your machine
Run echo "{\"title\": \"Issue title\"}" | git hash-object --stdin -w
. This takes your input string, in this case a bit of JSON, generates a SHA1 hash that represents that JSON string, and adds it to Git’s internal object database.
Run git update-ref refs/issues/1 {object hash returned from the previous step}
Navigate into the .git
directory at the root of your repo. ls refs/issues
shows us that our first issue is stored in the Git database! If you cat refs/issues/1
, you should see the hash that was calculated earlier.
Running git cat-file -p {the object hash}
outputs the original JSON string.
You can read more about Git refs here.
Why build it?
I’ve been using git since the start of my career in 2013 and I’ve been (blissfully) ignorant of its predecessors. I trust the old guard when they describe the pain of using what came before. Despite the criticisms that people lob at Git’s UX, it’s a pretty incredible system. I can write code on my own machine, send that code to any remote machine, even one I own, and collaborate with others to build software. No proprietary, centralized server needed.
Except when you do need one. The process of building software is more than just source code and commits. Communication between those building the software is missing from Git. That’s not entirely true; Git has a email-based system for submitting patches. But it’s a pain to use. That’s probably a skill issue on my part, but I think the UX leaves something to be desired. GitHub stepped in to fill that void and it has been incredibly successful. What if that gap could be bridged without relying solely on a third-party web app? To be clear, you could host your own instance of Gitlab, but as far as I know, things like issues and pull requests won’t be portable outside the server. I want credible exit for not just my code, but for everything around it.
These ideas weren’t generated in a vacuum; I’m inspired by tools like git-bug, git-appraise, ticgit, Fossil, and gh-dash. All have some awesome ideas and approaches to the problems I’ve been thinking about, but there’s no better way to understand them than building my own system.
If you’re interested in Git, improving the process of building software, or building apps for the terminal, stay tuned.