Golang
gini: a no-fuss CLI for editing INI files
A small Go utility to read, write and delete keys in INI files from shell scripts
INI files refuse to die. Samba, PHP, Git, MySQL, half of /etc — they’re everywhere, and editing them from a shell script is annoying enough that people reach for sed, regret it, and then write a much worse bug. gini is the tiny tool I wrote so I could stop doing that.
gitlab-mcp: drive GitLab from Claude Code without leaving the terminal
An MCP server that exposes GitLab issues, labels, epics, and CI/CD pipelines as tools Claude Code can call directly
I spend a lot of time in Claude Code, and a lot of time in GitLab. The constant tab-switching between the two — copy an issue ID, paste it into a prompt, jump back to read a job log, paste that too — got tiresome. So I wrote gitlab-mcp, a Model Context Protocol server that lets Claude Code talk to GitLab directly.
gitlab-token-expiration: stop getting surprised by expiring GitLab tokens
A CLI that lists every expirable token across your GitLab projects, groups, and personal account so you can plan rotations
GitLab access tokens expire. Project tokens, group tokens, personal access tokens — all of them. The trouble is that the expiration dates live in different corners of the UI, and you usually find out one expired the morning a CI pipeline mysteriously starts failing.
gitlab-token-expiration is the small tool I wrote to never have that morning again.
gocrypt: a tiny AES-GCM file encryption CLI
A small Go command-line tool to encrypt and decrypt files with AES-128 or AES-256 in GCM mode
Sometimes you just need to encrypt a file. Not set up a key management system, not learn the gpg command line again, not pull a heavy dependency — just turn secrets.txt into secrets.bin with a key you control. That’s the niche gocrypt fills for me.
How Go Channels Work: The Behavior Matrix
A practical guide to Go channels — receive, send, and close behavior across nil, unbuffered, buffered, and closed states
Channels are Go’s primary tool for coordinating goroutines, but their behavior changes drastically depending on their state. A channel can be nil, unbuffered, buffered, or closed — and the same operation (send, receive, close) does something different in each case. Getting this matrix wrong is how deadlocks and panics happen.