Posts tagged with "FOSS"

Reviewing token usage

3 min read; 7 GFI

As I've written about a few times in the last week or so, the journey with AI-based coding tools has hit an interesting time when it comes to prices, quotas, usage, availability and all that. Having come into all of this via a place where it was a flat fee, and where I didn't really need to think about input tokens and output tokens and so on, I'm pretty ignorant of what that all means in terms of scale. If I'm looking at a new tool and I see prices and/or quotas for in/out tokens, it means nothing to me. I can't relate to it. I've never had to care about it.

While using Gemini CLI to quickly make a change to BlogMore this morning, I was reminded that at the end of a session it does tell me this:

Session usage

Seeing that got me thinking: is there a way to get the total usage for all of my sessions, or at least the sessions that have still been retained (I'm guessing they expire after a wee while)? After a little bit of searching I found ccusage. That looked exactly like the sort of thing I was after.

Now, this is only going to be good for Gemini (it says it supports Copilot too, but it seems to be failing to find any Copilot sessions), but it should give me a feel for what my token usage looks like.

I work on BlogMore on two different machines: the MacBook Air and also a Mac Mini I have in my office. Here's all of the available token usage data I can get out of the Air:

DateInputOutputCache ReadTotal TokensCost (USD)
2026-04-29235,23820,282773,6421,032,608$0.23
2026-05-01315,0013,181447,556768,532$0.20
2026-05-022,621,62852,29018,260,59720,955,447$2.44
2026-05-033,627,84630,53811,819,27915,509,213$5.74
2026-05-04869,82949,1632,721,0743,656,649$0.77
2026-05-092,287,76050,0819,973,76412,327,819$1.84
2026-05-101,019,55034,5568,061,8979,125,838$1.05
2026-05-111,112,12335,61010,523,34811,689,576$1.24
2026-05-131,506,51341,8027,561,1689,124,651$2.88
2026-05-15123,1613,155587,248716,813$0.11
2026-05-16111,33414,836519,161646,275$0.13
2026-05-17940,48536,1717,682,3148,706,034$1.41
2026-05-1867,0331,357205,921275,707$0.05
2026-05-2160,9041,182119,055184,117$0.05
Total14,898,405374,20479,256,02494,719,279$18.13

And also the same for the Mac Mini (which gets used less frequently for this sort of thing):

DateInputOutputCache ReadTotal TokensCost (USD)
2026-05-04212,17831,6312,128,0742,389,927$0.36
2026-05-051,108,90331,9976,222,8687,374,732$1.13
2026-05-0830,8991,19464,07498,146$0.03
2026-05-111,339,33327,3998,074,9049,459,253$1.21
2026-05-12952,05753,02312,751,53913,838,943$1.52
2026-05-18166,8754,774651,417827,746$0.22
2026-05-19449,08723,9763,236,3243,721,558$0.54
2026-05-22335,15110,0121,919,8152,272,553$0.32
Total4,594,483184,00635,049,01539,982,858$5.33

In both cases I've removed a couple of columns to make the tables fit better. The first was the model name (varying between gemini-3-flash-preview and gemini-3.1-pro-preview), the second was Cache Create (which was always 0 all the way down).

From what I can see, it would appear that these two tables do cover my increasing use of Gemini CLI for doing work on BlogMore (the first intensive use being back around the 5th of this month, if I recall correctly). So this would seem to be a reasonably informative way to view things.

All of which is to say, over a roughly three week period, while getting things done, I've used getting on for 20,000,000 input tokens, and around 600,000 output tokens (presumably I do also need to be keeping the 114,300,000 cache read tokens in mind too). With this in mind I might now be able to make more sense of the pricing I see for various tools.

Reviewing the cost of BlogMore

3 min read; 8 GFI

Now that we're near the end of the free or cheap GitHub Copilot party, I thought it might be interesting to look at how much BlogMore has "cost" me to build, and what it would have cost under the proposed new pricing structure that is coming in next month. While I've looked at the comparison for last month, I've not looked at the whole period I've been seriously using it.

So, for this review, I'm looking at all the data I can pull out of GitHub for the months of February, March, April and May of this year. Development of BlogMore started back in February and, while it hasn't been 100% the cause of my use of Copilot premium requests, it's been almost all of it. For the purposes of this review I'm just going to take the approach that all I worked on was BlogMore.

Remember that, even when I had free access, I had a maximum of 300 premium requests per month. Once I lost free access I had the same number of requests for $10 a month.

Here's how those months broke down:

MonthPaidPremium Requests%agePredicted Price
February$0.0024983%$21.67
March$10.0014047%$56.38
April$10.0013244%$53.77
May$10.003411%$53.69
Total:$30.0055546%$185.51

So, give or take, something that I've actually spent $30.00 on could have, at best, cost me $185.51. That's assuming that the "cost" of the models I was using stays the same. You can see that the costs have risen already in that the predicted price from February, where I used 83% of my premium requests, is a touch under half the cost for this month, where I've used just 11%. From what I can see in the raw data, it's down to some models suddenly being considered more expensive (perhaps I was doing something that just consumed more tokens, I'm not 100% sure if I'm honest, but I don't recall anything that seemed like harder work).

Who knows what the real costs will be come June.

Now, technically, the actual cost under the new regime could or should be $156, because it would be 4 lots of the $39.00/month plan, which would better cover that use1. Again though, that's assuming the actual cost of using whatever models remains pretty stable. It also assumes that I'd want to spend that much each month, and that I would be correctly anticipating that I'd need that much.

Also, this isn't even the total cost of getting this project done. As I've written recently: I've been using Gemini CLI more this month, and while the usage there is a flat cost, until now, that's changing too.

Now, of course, these aren't the only games in town. I could "go to the source" and just get a sub for Claude Code or something, and as Tim pointed out over in the Fediverse, something like Cursor does a lot of this and is just $20/month. Which all sounds fine, but what happens when those fleeing GitHub Copilot or Gemini CLI/Antigravity head over to something like Cursor? Is it sensible to expect the pricing to stay the same2?

I guess, at this point, I'm just mulling over the same issue time and again, but from different angles. It does seem clear to me, though, that in less than 4 months, in my experiment of "what happens if I use agents to develop a Free Software tool I want?", the market has gone from being entirely reasonable to pretty much unjustifiable from a price point of view.


  1. As I understand it, the $39 gets you almost twice that value in "AI credits", so the base allotment plus the flex allotment would cover what I've used. 

  2. That's not even the main reason to be concerned about a switch to Cursor

More syncing GitHub to GitLab and Codeberg

1 min read; 10 GFI

Following on from my first post about this, I've tweaked the script I'm using to backup a repo to GitLab and Codeberg:

#!/bin/sh

# Check if the current directory is a Git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
    echo "Error: This directory is not a Git repository."
    exit 1
fi

REPO_NAME="$1"

# If no repository name was provided, try to get it from the origin remote
if [ -z "$REPO_NAME" ]; then
    ORIGIN_URL=$(git remote get-url origin 2>/dev/null)
    if [ -n "$ORIGIN_URL" ]; then
        REPO_NAME=$(basename -s .git "$ORIGIN_URL")
    else
        echo "Error: No repository name provided and no 'origin' remote found."
        echo "Usage: $0 <repo-name>"
        exit 1
    fi
fi

echo "Configuring multi-forge backup sync for: $REPO_NAME"

# Set up the remote called backups. Anchor it to Codeberg.
git remote remove backups > /dev/null 2>&1
git remote add backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"

# Set up the push URLs.
git remote set-url --push backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"
git remote set-url --add --push backups "git@gitlab.com:davep/${REPO_NAME}.git"

# Only ever backup main.
git config remote.backups.push refs/heads/main:refs/heads/main

# Also backup all tags.
git config --add remote.backups.push 'refs/tags/*:refs/tags/*'

echo "----------------------------------------------------"
echo "Backups configured:"
git remote -v
echo "----------------------------------------------------"
echo "To perform the initial sync, run: git push backups"

### setup-forge-sync ends here

The changes from last time include:

  • The repo name now defaults to whatever is used for GitHub, so I don't have to copy/paste it or type it out.
  • It now backs up all the tags too.

I've been running with this for a couple of days now and it's proving really useful. Well, when Codeberg is available to push anything to...

More Codeberg issues

1 min read; 11 GFI

As I've said earlier, I'm not looking to move off GitHub any time soon, but I am curious about evaluating the options. So far, while trying out Codeberg, I am finding it to be very unstable.

A little earlier I was simply browsing some of the repositories I've been adding and got very slow load times, and then a 500.

Codeberg 500 error

As I've said elsewhere: I really wouldn't expect perfection. I doubt that Codeberg has the money behind it that GitHub does. But, again, there is that issue with moving off GitHub because of instability; from that point of view it would feel like swapping some occasional instability for what, at the moment, is feeling like regular instability to the point that I wouldn't get too much done.

Syncing GitHub to GitLab and Codeberg

2 min read; 10 GFI

I've had a GitLab account since December 2017. This came about because of the new job I started in January 2018. They used a self-hosted internal instance of GitLab for all their code, so it made sense I get familiar with it (it wasn't hard; especially back in 2017 it was near enough a clone of GitHub in terms of what it did). Since then, though, I've never really done anything with it. I think I had a repo or two on there for a short while, but I must have nuked them at some point because the account has been empty for the longest time.

A Codeberg account, on the other hand, only got created the other day. Having created this, I got to thinking about how I might use it. In doing so I thought back to my GitLab account and then also got to thinking about where all my public code lives, and how "safe" it is.

Now, sure, the whole point of Git is that it's distributed. Forges are a useful thing to have and work with, but they shouldn't be the place where your code lives. On the other hand, I've had so many machines, and so many work environments, that it has become the case that my GitHub account has become the storage location for my code and projects.

Mostly this is fine. If GitHub were to disappear tomorrow I imagine we'd all have bigger things to be worrying about anyway. But the principle stands: why not distribute the load? Why not distribute the effort when it comes to sharing code I write?

So yesterday I finally decided on a plan: for the moment at least, I'm going to keep using GitHub as my "primary" location for working on stuff. It's where I'll have WiP branches, it's where I'll keep issues, it's where I'll encourage people to raise requests and stuff, it's where I'll host this blog. But I'm going to start syncing projects to both GitLab and Codeberg. I see this as having two benefits: anyone who doesn't want to interact with GitHub can now easily fork code, and if they wish they can raise issues and the like too. Meanwhile, in doing this, I'll also have the added benefit of my code being "backed up" in at least three different locations1.

The approach I've settled on, for the moment, is based around this little shell script:

#!/bin/sh

# Check if a repository name was provided
if [ -z "$1" ]; then
    echo "Error: No repository name provided."
    echo "Usage: $0 <repo-name>"
    exit 1
fi

REPO_NAME="$1"

# Check if the current directory is a Git repository
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
    echo "Error: This directory is not a Git repository."
    exit 1
fi

echo "Configuring multi-forge backup sync for: $REPO_NAME"

# Set up the remote called backups. Anchor it to Codeberg.
git remote remove backups > /dev/null 2>&1
git remote add backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"

# Set up the push URLs.
git remote set-url --push backups "ssh://git@codeberg.org/davep/${REPO_NAME}.git"
git remote set-url --add --push backups "git@gitlab.com:davep/${REPO_NAME}.git"

# Only ever backup main.
git config remote.backups.push refs/heads/main:refs/heads/main

echo "----------------------------------------------------"
echo "Backups configured:"
git remote -v
echo "----------------------------------------------------"
echo "To perform the initial sync, run: git push backups main"

### setup-forge-sync ends here

I'm going to keep all repo names the same2. So when I use this script it'll set things up so I can git push backups and main will then get pushed up to both GitLab and Codeberg. I don't feel the need to be keeping any WiP branches in sync or kicking about, likewise any gh-pages branches.

While I'm sure I could have done something a little more automated, this feels like a neat and simple approach, and also allows me to curate what appears in the two other places over time (I suppose, eventually, I'll mirror everything that isn't a dead experimental repo, but meanwhile I'll prioritise projects that are either still very useful or which I'm actively developing and maintaining).


  1. Yes, I have other backups too, but they're always current-working-machine type backups. 

  2. Except, perhaps, for any repo whose name starts with .; I seem to recall that GitLab can't handle that, for some bizarre reason. Perhaps that's fixed now? 

Trying out Codeberg

2 min read; 8 GFI

Following on from what I wrote about GitHub recently, I thought I'd check out Codeberg. While I'm aware of it (it is supported by Hike after all), I've never actually used it and have never had an account there.

I was delighted to find my preferred user name was actually available, which made me more inclined to create an account. The account creation process itself seemed a bit of a faff. I can't remember the details now, but it took a couple of goes and necessitated a password reset and recovery to actually get in (I recall there was some sort of error when I tried to use the activation link sent in the email, which took quite a while to turn up, but the rest is hazy, and I wasn't taking notes). It might be that it didn't help that I was signing up in a mobile browser.

That aside, though, I got up and going in the end.

At this point I'm not quite sure what I want to do with the account. While I'm nowhere near being willing or able to move my GitHub activity over there, it at least feels like it might be a viable backup location via which I can make code available. Also, and probably more importantly, it makes it easier for me to follow projects that use it as their primary (or only) forge.

This morning I found myself following a link to a project hosted there. It looked interesting, it looked like something I'd want to follow. It didn't go so well. I hit the star button and... busy circle.

Slow star

This lasted for a while with nothing happening. So I refreshed the page, no star on the repo, so I tried again. Same result. I tried a third time and got something different right away.

Codeberg error

At some point I ended up with a big fat 500 page.

Do I see this as an issue? Of course not. Could be I caught it on a bad day. Stuff happens. I've seen a 500 from things I'm responsible for before now. I'm not going to expect perfection. But it does remind me that leaping from one forge to another, to chase platform stability, and in doing so give up a long history, is a risky endeavour without a guaranteed payoff.

On GitHub

2 min read; 12 GFI

It seems that dunking on GitHub is the flavour of the day. At the moment most of the social/news type things I tend to read are filled with the Ghostty news, as well as a small revival of posts and links to blog posts about all the recent outages. It's understandable. It does seem that something has shifted with GitHub in the last few months. While it hasn't been the site I used to enjoy for quite some time now, it just seems to be getting worse at the moment.

It's even pissing off the loyal AI enthusiasts with the Copilot changes.

As I read all of this I find myself mostly nodding along. For the most part I'm not finding that GitHub is getting in the way and stopping me from doing the things I want to do, and for the most part it does act as a vital tool that lets me get work done, and also lets me enjoy my longest-enjoyed hobby. On the other hand I couldn't help but sigh and think "yeah, I get why this is the time that people are done" when I opened up the PR page for this blog, just now, and saw this:

A warning about my PRs

It does get me thinking about my relationship with GitHub, and how long I've been using it. As I've written before, I created my account back in 2008; I was within the first 30,000 users. While my use of it was only very occasional for quite a long time, for the last decade I've been constantly interacting with it. It is somewhere I visit constantly, not just to do work on my own projects, but to read what other people are doing. One of the first things I do every morning, when I sit down at my desk, is open my GitHub dashboard page and have a scroll through the feed to see what people I follow have been up to.

It's generally been the most fulfilling feed I've read.

But I'm also getting that feeling I got when I hung on to my Twitter account far longer than I really should have; not just because of the general vibe of "it's falling apart", but also other types of questionable behaviour. The degrading performance, the troubling business relationships, the over-emphasis on all things AI... it adds up.

There is a sense that some time ago was the time to move elsewhere as my sociable forge (probably around the time that Microsoft took over), and that not having done that, now is the second best time. But the effort of making that move is non-trivial and, quite frankly, I'd want to see where folk start to land, if they started to move away in any numbers at all. For me the real utility of GitHub isn't the "it's somewhere to store my shit" thing, it's the socially coding thing.

Then there's the follow-up problem: if some other forge was to become the next flavour of the decade, it too would probably end up suffering the same fate as GitHub.

Perhaps now is the time for me to start looking into options for collaborative code forges that offer the same sort of solution that Mastodon does for Twitter-like nattering.

unabbrev.el v1.0.0

3 min read; 9 GFI

Back in the late 1990s, like plenty of people who were very online, I was a very avid user of Usenet. There were a few groups I was very active in, even a couple that I maintained a FAQ for. Being that active and wanting to help and answer questions, I was forever posting and pasting links to various resources. Given that I used Emacs to edit my posts1, I eventually realised that I should come up with a tool that let me call on common URLs quickly.

So back in 1998 handyurl.el was born. It was a simple idea: have a file of URLs that I commonly refer to and let me quickly pick from one and paste it. This made for a useful tool and also gave me something to build given I was learning Emacs Lisp at the time.

For reasons I can't quite recall, some time later (the next year, by the looks of things), I wrote quickurl.el as a successor to handyurl.el. I honestly can't remember why this happened, I can't remember why I didn't just keep extending handyurl.el. But, anyway, quickurl.el did more and was more flexible, with built-in URL-grabbing and editing and so on.

Not that long later I got an email from the FSF asking if I might be willing to hand over copyright so that quickurl.el could become part of Emacs itself. I was, of course, delighted to do so.

Eventually quickurl.el was declared obsolete and, while it seems to still be shipped with Emacs, it's not documented or easy to discover.

In the deprecation notice in NEWS the suggestion is that the user should switch to one or more of 3 alternatives:

** The quickurl.el library is now obsolete.
Use 'abbrev', 'skeleton' or 'tempo' instead.

abbrev I know, the other two I've never noticed and don't know anything about.

Obviously, between quickurl.el being pulled into Emacs, and it being made obsolete, my use of it fell right off. I eventually stopped posting to and reading Usenet, I also stopped using mutt+Emacs as my mail client of choice, and so found myself seldom writing things that needed lots of links, in Emacs.

Until recently.

At the moment I'm finding that I'm wanting to write on my blog more and more, and doing that means I often want to include some common links, and I write my posts in Emacs using markdown-mode and with a little help from blogmore.el; the need to have an easy-to-pick-from common menu of URLs is back.

Driven by this I've made a point of using abbrev to initially solve this problem. This works, but I do have a problem: I keep forgetting what the abbreviations are. I find myself wanting to have a key binding that lets me at the very least completing-read the desired abbrev. So yesterday I quickly knocked up unabbrev.el.

It's simple, straightforward, small and does the job I needed. Doubtless there's something else out there that can do this sort of thing too, but part of the fun of Emacs (for me) is that I find I have a need and I can hack together some Lisp and get that problem solved.

The code in action

I suppose what I should do is revive either handyurl.el or quickurl.el and tweak and update whichever, at the very least adding some sort of insert formatting facility that is sensitive to the underlying mode (because links in Markdown need a format different from links in HTML, etc).

For now though unabbrev.el is going to help my failing memory when I want to link a common resource.

As an aside, all of this does have me wonder about one thing: is the Free Software Foundation the place that code goes to die? Like, sure, of course I can make changes to quickurl.el and do my own thing with it, as long as I don't misrepresent the copyright status and maintain a compatible licence, etc; but there is this thing where, if Emacs doesn't want that code any more, if the FSF don't want that code any more, wouldn't it be nice if they'd sign it back over again?

I am tempted to drop them a line and see what the deal is. I did tag-ask on Mastodon but got no reply. Unfortunately though that account looks like the FSF treat Mastodon as a write-only resource.


  1. But curiously never got into Gnus, my news client of choice was slrn and I composed posts in Emacs. 

Astral and OpenAI

1 min read; 10 GFI

It's a couple of days now since the news hit that OpenAI are in the process of purchasing Astral. When I first saw this my initial reaction was pretty much "woah", followed by getting on with what I was doing.

Until, that is, I opened up the socials. On Mastodon, Reddit, Bluesky, Threads, etc... anywhere I followed any Python-based content, I was seeing very firm opinions posted. Plenty of folk either talking like it was the end of their tooling as they know it, or proudly boasting that they'd avoided uv and ruff (and lately ty too I guess -- not that I've really tried that yet myself) because they'd predicted this evil outcome from the start and they were untainted by this but look at all you idiots who fell for this long play!

Okay, I exaggerate slightly, but there were some pretty strong opinions kicking around, especially in the (often fairly smug) "I stayed pure and never used uv" camp.

Personally, I don't get it. The last I looked the tools I use that Astral are behind are FOSS. Also, the last I looked, plenty of FOSS tooling is written by folk who are either paid to do so (I had my moment), given some time in the day job to work on those tools, or just plain have a day job and also work on those tools. If, as plenty are speculating, the Astral purchase is an acqui-hire, the likely result is going to be one of those three scenarios.

If it isn't one of those scenarios, if work on uv and friends just ceases, well, at best some smart folk can fork the tools that are useful and keep them going (this is a major benefit of FOSS after all) and, at worst, well... we can fork them and agent the shit out of them. Right?