Rust

codex-status-json

I made a small Rust CLI that prints Codex status as JSON.

The short version is that I wanted Codex conversations to know my account, model, and quota state without opening the interactive TUI and reading /status like a person.

This is mostly useful with Codex goals. I am on the Pro 20x plan, which is the $200/month tier, so sometimes I really do have quota to burn. If I can read the remaining quota first, I can make a goal with an actual target instead of guessing how ambitious I should be.

The missing command

Codex has /status in the interactive CLI. It shows useful stuff: account, model, context, writable roots, and rate limits.

That is fine when I am sitting in the TUI. It is less fine when I want another Codex conversation to ask the same question.

There is an upstream issue asking for this exact kind of thing: a non-interactive JSON/headless replacement for /status. The issue is still open as I write this. There is also codex doctor --json, which is useful, but that is a diagnostic report. It is not the same as “tell me my account/model/quota status right now.”

So I made codex-status-json.

The first version was worse

The first version did what you would expect from a tool born out of impatience: it opened Codex in a PTY, sent /status, waited for the panel to settle, captured the terminal output, stripped ANSI escapes, and parsed the text.

It worked. It was also clearly a bad long-term place to live.

Terminal scraping is annoying because every little UI change can break you. The parser has to care about box drawing, timing, update notices, trust prompts, terminal width, and whatever else the TUI happens to render that day.

Still, it was useful. It gave me JSON like this:

{
  "schema_version": 1,
  "account": {
    "email": "user@example.com",
    "plan": "Pro",
    "raw": "user@example.com (Pro)"
  },
  "model": {
    "name": "gpt-5.5",
    "details": "reasoning high",
    "raw": "gpt-5.5 (reasoning high)"
  },
  "buckets": [
    {
      "name": "default",
      "limits": [
        {
          "kind": "5h",
          "remaining_percent": 99,
          "resets": "14:44",
          "reset_at_unix": 1780350290
        },
        {
          "kind": "weekly",
          "remaining_percent": 70,
          "resets": "08:23 on 7 Jun",
          "reset_at_unix": 1780845815
        }
      ]
    }
  ]
}

That was enough to unblock the thing I wanted.

The less cursed version

A few days later, I switched the default backend to Codex’s app-server.

That is a much better source than scraping the TUI. The tool starts:

codex app-server --listen stdio://

Then it sends JSON-RPC calls for:

  • account/read
  • account/rateLimits/read
  • config/read

That gives it the same kind of account, model, and quota information without pretending a terminal status panel is an API.

Important caveat: Codex app-server is documented, but it is also described as experimental and may change. So this is still not a supported codex status --json. It is just a more sensible workaround than screen scraping.

The PTY backend is still there as a fallback:

codex-status-json --backend pty

But the default is now:

codex-status-json --backend app-server

This is a bridge

I do not expect this to be the forever answer.

Codex’s usage and billing surface is still moving. OpenAI has already introduced things like banked rate-limit resets, so the status shape is not just “two counters and call it done.” There are plans, windows, reset times, secondary buckets, and whatever else comes next.

So I can see why OpenAI might not want to commit to a stable status JSON contract yet. That is fine. I still wanted something local that worked now.

This is the same kind of bridge as a lot of these small tools: use the available pieces, make the annoying gap tolerable, and be happy if the official thing eventually replaces it.

The repo

The project is here:

https://github.com/nelsonjchen/codex-status-command

Install it locally with:

cargo install --path .

The README has the options and limitations. The tests include a captured /status fixture so the text parser can at least fail loudly when Codex changes its display.

I would still rather have an official codex status --json. Until then, this is small, local, and useful enough.

3:03 pm / Codex , Rust , CLI , JSON , Automation

Moving Gmail Send mail as to Cloudflare SMTP

I just finished moving my Gmail “Send mail as” setup completely to Cloudflare Email Service’s native SMTP submission. I can send out emails under my mindflakes.com domain.

The short version is that I had built a small Rust SMTP-to-Cloudflare REST API relay in April. Today I noticed Cloudflare had shipped native SMTP submission.

Part of the appeal here is minimizing vendors. Cloudflare already hosts the domain, handles incoming mail through Email Routing, and now can handle outgoing mail through Email Service too. For a personal domain, that can be cheap or free, and it is a nice alternative to paying for Google Workspace when a personal Gmail account is otherwise fine.

The April hack

In April, I saw Cloudflare’s public beta announcement for Email Service and got excited about using Cloudflare for both inbound and outbound personal-domain mail.

Then I got sad. I wanted Gmail to send mail for one of my domains through Cloudflare Email Service, but I did not see a native SMTP submission path I could just point Gmail at.

Gmail’s Send mail as feature wants a normal authenticated SMTP server. You give it a hostname, a port, a username, and a password. Gmail talks SMTP. It does not want to be handed a REST API endpoint.

[... 668 words]

2:13 pm / Rust , SMTP , Cloudflare , Gmail , Email

Blocking spammy caller names with VoIP.ms Call Hunting

I made a small Rust VoIP.ms CNAME blocker.

The short version is that I wanted to block a caller by name instead of by phone number.

This sounds like it should be an option in VoIP.ms. For all the features VoIP.ms has, this is not one of them. So I made one for cheap.

The missing filter

VoIP.ms has a pretty capable CallerID Filtering feature. You can filter on specific caller ID numbers, phone book groups, anonymous callers, calls that do not match the North American number format, STIR/SHAKEN attestation level, and wildcard patterns like area-code-ish blocks.

That is all useful, but these asshole spam callers and scammers do not politely stick to one number. They rotate numbers. Blocking one just means the next call comes from another one. What I wanted to block on was the caller ID name.

VoIP.ms has CNAM support too, but as far as I can tell it is for displaying names, not filtering on them. Their blog post on stopping spam calls talks about filtering numbers, area codes, and anonymous callers, while describing CNAM as a way to identify callers before picking up. The Caller ID wiki page describes incoming Caller ID name lookup as an optional per-DID setting that can display a caller name for US and Canadian callers.

[... 718 words]

7:30 pm / Voip , Sip , Rust , Voip ms , Telephony

GitHub Wiki SEE: Search Engine Enablement

I built this in March, but I figure I’ll write about this project better late than never. I supercharged it in June out of curiosity to see how it would perform. It’s just a ramble. I am not a good writer but I just wanted to write stuff down.

TLDR: I mirrored all of GitHub’s wiki with my own service to get the content on Google and other search engines.

If you’ve used a search engine to search up something that could appear on GitHub, you are using my service.

https://github-wiki-see.page/

Did you know that GitHub wikis aren’t search engine optimized? In fact, GitHub excluded their own wiki pages from the search results with their robots.txt. “robots.txt” is the mechanism that sites can use to indicate to search engines whether or not to index certain sections of the site. If you search on Google or Bing, you won’t find any results unless your search query terms are directly inside the URL.

The situation with search engines is currently this. For example, if you wanted to search for information relating to Nissan Leaf support of the openpilot self-driving car project in their wiki, you could search for “nissan leaf openpilot wiki”. Unfortunately, the search results would be empty and would contain no results. If you searched for “nissan openpilot wiki”, “https://github.com/commaai/openpilot/wiki/Nissan" would show up correctly because it has all the terms in it. The content of the GitHub wiki page is not used for returning good results.

[... 1,550 words]

6:12 pm / Github , Wiki , Seo , Rust , Cloud run , Bigquery , Gcp

GitHub Wiki SEE

https://github-wiki-see.page/

A project to get GitHub Wikis indexed by Google Search.

Explanation is right on the front page.

If a search engine can’t see it, it may as well be invisible.

Long-term project involving Rust, BigQuery, Cloudflare Workers, and lots of random hosting.

Probably one more the more visited sites on the internet and a continous effort to keep costs low.

Has caused GitHub to revisit their policy on a limited subset of Wikis meeting some criteria.

Will continue until all Wikis are indexed even if they are publically editable or don’t meet some star count criteria.

Personally, I just got really dismayed all this documentation I was doing on a Wiki wasn’t visible to Google. Then I realized it was a good idea to make it visible. Then I realized others don’t realize it was invisible at all. This was a problem.

12:00 am / Github , Wiki , Seo , Rust , Cloud run , Bigquery , Gcp , Flyio , Cloudflare