Skip to content

Spring & summer projects update

How is it September already?…

Kuba Suder 🇵🇱🇺🇦
Sep 2, 20269 min read
1

his is an irregular periodical update about what I've been working on in recent months :)

(Warning: vibe-coding will be mentioned, more than once…)

New projects

RatProto 🐀

This is a Ruby command-line tool that combines several of my ATProto Ruby gems to do a few unrelated things that might be useful to quickly run from the command line, like:

  • fetch a record by at:// URI
  • look up a DID document or resolve a handle
  • check an account's status
  • stream filtered events from a firehose or Jetstream

I wrote about it here:

Article

CSP Maker 📃

This is basically just the ActionDispatch::ContentSecurityPolicy class for defining a CSP using a DSL, extracted from Rails to a standalone gem, so it can be used inside Sinatra/Rack or other apps. The DSL is the same, all the integrations with Rails are removed, and there's an optional Rack middleware that doesn't depend on ActionPack.

I had a helper like this before copy-pasted in a few projects, but I figured it's better to have it included from a single place.

Oxygène

This started as wanting to redesign the repo import process in Lycan, realizing I don't have code for parsing repo .car files, building that code using what I had in Skyfall, then realizing it's really slow, and ended up as a 2-week-long session with Codex, going through many cycles of profiling & optimization, and eventually the lower layer of parsing-related parts got extracted to a new gem I called Oxygène, so you can use those without importing the firehose-related parts. I wrote about this here:

Article

Minestrone 🍲

This is, uh… a mostly vibe-coded simplified fork of old Capistrano 2. Yeah, I know…

See, I started using Capistrano for Ruby app deploys in early 2010s when I was working for a Rails software house, I had it configured in all my Ruby apps, and I didn't really have a reason to change it. If it ain't broke… But using outdated software is not always good for various reasons, and Capistrano project moved on to v. 3.x long ago. Except this was more of a full rewrite, changing a lot of things in the API, and I knew from looking at the docs a few times over the years that I'd need to spend a day or two going through all the documentation, updating my configs, plus some things like the "copy" strategy (deploy straight from local disk vs. from a git repo) which I sometimes use were removed, so I'd need to find a way to do them differently. So that's work, with probably not much benefit. So I just stuck with the legacy 2.x branch for over a decade, since it worked as is.

I asked around sometimes what things like that people use these days, but it seems that most use some kind of Docker/container based systems, which I… really don't want to get into, and those few who don't, use some kind of custom-made deploy scripts, or maybe Nix. There's another simpler Ruby deploy tool called mina, but it doesn't seem to be maintained anymore.

So I finally decided to bite the bullet, read the docs properly and update all my configs. I started doing that, and in the end… the whole thing worked slower. Well thanks for nothing.

It seems that this rewritten system in Cap 3 based on their "SSHKit" library, with a maybe cleaner but much more verbose DSL, also inherently makes much more calls to do the same thing, cd'ing to a directory for every command or running some checks for file/directory existence, I don't remember exactly. But it was something like 15s to 30s difference in deploy time. Not a huge deal, but why would I do work in order to make things worse?

This doesn't necessarily mean it's a bad tool, it just always had a focus on slightly more complicated setups (I've literally never used the roles thing there), and with the rewrite it went further in that direction, at the cost of simpler use cases.

So in the end I thought: ah fuck it, I'm just gonna fork it. And since this was a time when coding agents got really good already, I asked the bot for help, first to understand what the architecture of the project was, and then to gradually strip out everything I don't need: support for multiple servers, roles, stages, parallel commands, weird deploy strategies, obscure version control systems, and so on. Just keep a way to deploy a Ruby app to one server from git and run some extra tasks, with the revision system, callbacks and so on. And the remaining code should be much easier to understand and maintain going forward.

I called it "minestrone", because "mini capistrano… ministrano?" 🙃 (Also I like soups.)

I didn't put much more work into it, but I've switched the deploy configs in all my Ruby apps to this forked version and everything works fine, plus I managed to simplify/remove some boilerplate that was required in 2.x for historical reasons, and added support for latest Bundler.

If someone's interested in using this tool, I'll be happy to help and add some things if needed, but if not (more likely), I'm totally fine just being the single user of it, it solves my problem.

mackuba.eu/minestrone

A simplified fork of old Capistrano 2.x - a tool for deploying Ruby applications to a server

Blog

I started a new series of blog posts on my main blog called "ATProto in practice", which currently has 1 episode ;) about DIDs & handles. But a second one (about XRPC APIs) is coming soon, hopefully.

Article

Also, I replaced the old local comments system there with comments loaded dynamically from Bluesky & Mastodon, plus I also added support for standard.site to the blog, syncing new & updated posts to my PDS on deploy:

Article

And, I finally got rid of jQuery there! 😂 (it was used for a very old lightbox plugin)

Updates

blue.mackuba.eu

  • on request from @richferro.com from Latinsky/Medsky, I added a detail view in the PDS stats table which shows how many accounts on the PDS use which handle suffix:

(currently this only shows up for Blacksky PDS, since it's the only big one that has multiple handle choices)

  • added a chart on the stats page that shows how the major non-Bluesky PDSes are growing:
  • also on this "weekly users per origin" chart, you can now toggle this % checkbox to see what % of all Bluesky users are posting on non-Bluesky PDSes, and how this changes over time:

Skythread

  • added a profile info popover with bio, pronouns, PDS info, and account creation date:
  • the "hidden replies" view now tries to get more info about why a specific reply isn't visible on Bluesky, e.g. what state the relevant account is in:
  • and it also tries to detect when a reply was hidden because the author got the infamous "needs review" shadowban-like label:
  • also, post edits done via mu.social are displayed:
  • and inline code and code blocks are highlighted like in Mu too:
  • added support for new gallery image embeds (for now just as a list of [Image] links like for the old embed)
  • added support for Klipy & Giphy gifs, and they're displayed with a new custom placeholder view with alt
  • and… I've been working on OAuth support a bit, but I can't get myself to work on that too much 🫣

Pulsar

  • I added an "uptime" column – there's a background job that tests connection to one source every few minutes, which adds up to a few pings a day to every source, and the column will show the % of successful pings to a given server over the last month. (Not like a literal ICMP ping, just make a websocket connection and wait for one event.)
  • I'm also trying to improve the algorithms calculating the coverage %, to better detect which source was doing something funny during the test, and to avoid interpreting a result as one relay having 100% and others all having less (when really it's one reporting a too large number that should be ignored as an outlier) – this is still ongoing work.

Ruby gems

  • added support for parsing public keys from DID documents to didkit, and finally proper JWT token verification to Lycan (which should also find its way to blue_factory for feed viewer authentication at some point)
  • I'm gradually improving the test coverage further in some of the gems, which got much easier now with the help of robots :]

Experiments

Run Map

For many years I had this idea in my head of some kind of app (ideally a native Mac app) that would let me easily browse my whole history of runs & bike rides that I have collected in RunKeeper, Strava and HealthKit. To let me view old runs on some routes I've forgotten about and give me ideas of where I could go again. But this always remained on the todo list, because I felt like there was a bit too much work to get this to any usable point.

Well, not anymore, when you have a bot that can implement this for you in one afternoon!

I'll need to spend more time on this before this is anything close to releasable in any form, but it's looking promising and should already be of some use to me:

Hannibal

This is an experiment in building a Safari extension for bsky.app, which hacks it to display bridged Mastodon 🐘 posts in full length as if they were normal native posts, instead of showing them truncated to 300 characters with a link to the original post. I used it for a bit, but turned it off later because I think it's contributing to the high memory use of all my Safari tabs (it needs to store received JSON data and then use it to re-render post components), so I'll need to optimize it before I can use it "in production".

Other

  • I made a simple Webkit view wrapper Mac app for FB Messenger website, so I can have it sitting in the Dock, always at hand, and show notification badges when I get new messages. It kinda works and I use it to chat with my sister, but Facebook's Messenger webapp is really shit and often stops loading or stops working for no reason and needs to be reloaded… I miss their old official Mac app, which also wasn't native, but it was better than this. :\
  • I vibe-coded a Mac ToDo list app for myself, which is designed to work exactly with my workflow: a list of projects in the sidebar, each project has tasks just grouped into a few scopes like "ready to do", "later" or "someday", and states like not started / partially done / blocked / completed (with marking a task as started & in progress as a core feature). Organized as "here's a general list of things you could be doing first from all projects, pick one you feel like working on today", not "tasks I will do on Tuesday", because I don't work this way. You can select a project in the sidebar and have this project's tasks grouped into scope sections, or select a scope and see all tasks in this scope grouped into project sections. I've been using it as my main task management app for a few months now, and I'm pretty happy with it (despite some annoying UI bugs I need to find time to fix).

Boring ongoing maintenance

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions