Skip to content

DispatchesΒΆ

Ghostty: The Terminal Emulator That Refuses to Compromise

Ghostty logo

Most terminal emulators ask you to make peace with an awkward tradeoff. You can have something fast but austere, polished but slow, powerful but painfully non-native. Ghostty, created by Mitchell Hashimoto, is interesting because it doesn't merely try to improve one side of that triangle. It tries to make the tradeoff smaller. The result is a terminal that's GPU-accelerated, deeply configurable, standards-aware, and designed to feel native on whatever platform it runs on.

At the highest level, Ghostty is a modern terminal emulator for macOS and Linux. That sounds ordinary right up until you look at how it positions itself. The project is explicitly built around three goals:

  • Fast
  • Feature-rich
  • Native

The third goal is where the project gets interesting.

There are plenty of fast terminals. There are plenty of featureful terminals. There are also terminals that feel at home on a specific operating system. Very few try to be strong in all three categories at once, because that's much harder than slapping a fast renderer on a cross-platform UI toolkit and calling it a day.

Ghostty takes the harder path. On macOS, it uses real Apple frameworks. On Linux, it integrates with GTK4 and the surrounding desktop environment. Underneath those platform-specific shells is a shared Zig core that handles terminal emulation, rendering, and the heavy lifting that makes Ghostty feel so responsive.

If you spend a good chunk of your day in a shell, an editor, a multiplexer, or a remote session, that combination matters more than it may seem on paper.

GitHub Milestones as Release Payloads

Issues and pull requests accumulate quickly on any active project. Without structure, a repository becomes a flat list of work with no clear sense of what belongs together, what's blocking a release, or how close you are to shipping. Milestones give that structure: lightweight containers that define the payload of a release, track progress automatically, and surface what remains without requiring a separate project board or external tool.

This post covers how milestones work, how to name and manage them, how to operate them through the UI, the GitHub CLI, and the REST API, and how to automate the tedious parts with GitHub Actions. It's opinionated: these are the practices that work in production open source repositories, not a neutral survey of every option.

A milestone is a named container attached to a repository. It holds issues and pull requests, carries an optional description and due date, and displays a live progress bar computed from the ratio of closed to total items. Nothing more. That simplicity is the point.

How to Inspect Code in PyCharm and GoLand

Most developers first encounter JetBrains code inspections as red underlines and yellow warnings inside the editor. That live feedback is the same inspection engine behind Problems, batch runs, and shared profiles, even when the UI says "problem" in places. It's useful, but the bigger win is learning to run a deliberate inspection pass across a file, package, module, or whole project before you commit your changes and open a pull request.

That workflow lives in Problems, Project Errors, Code | Inspect Code, scope selection, and inspection profiles. Once you start using this, PyCharm and GoLand stop being fancy editors and become a code quality gate.

Applies Across JetBrains IDEs

My focus here is on PyCharm and GoLand because they're the tools I use most. The same inspection model also shows up across other JetBrains IDEs, though the exact inspection groups, plugins, and file-type support will vary by product and project setup.

By the time a problem reaches CI/CD, you've already paid the context-switch tax:

  • You wrote the code.
  • You staged it.
  • You pushed it.
  • You waited for the pipeline.
  • You reopened the work.

By contrast, when PyCharm or GoLand finds the issue locally, you can usually fix it while the code is still fresh in your head.

That's the value of leaning on inspections end to end. The IDE isn't only marking mistakes in the current file as you type. It can also run structured inspection passes against broader scopes of code and show you the results in one place, grouped, triaged, and ready to fix.

For a lot of Python and Go developers, that second part is the missing piece.

It also does something more subtle over time: It teaches you patterns.

If you keep paying attention to the same warnings, quick fixes, and inspection results, you start to pick up better habits before the IDE has to remind you.

Upload govulncheck Results to GitHub Code Scanning for Go

If you already use GitHub security features for Go, it's tempting to assume CodeQL and Dependabot cover everything you need. They don't fully replace govulncheck.

For Go projects, govulncheck adds a useful layer: it understands the Go vulnerability database and uses package and call graph information to reduce noise. That means it can help answer a more practical question than "is this module version mentioned in an advisory?" It can help answer "does this vulnerability affect code my project actually uses?"

That's enough of a difference that I think govulncheck is worth surfacing directly in GitHub code scanning, not just running as an isolated terminal command or a one-off CI step.

Busy != Important

I am not naturally good at time management. I can make a list, rearrange the list, rewrite the list in a better app, and still end the day with the uncomfortable feeling that I mostly attended to noise. The inbox moved. The calendar happened. A dozen small things got handled. The important work, the thing I knew mattered before the day started, somehow survived untouched.

That is the trap. Busy feels defensible. Busy gives you evidence. Busy lets you point at a full calendar and say, "See, I did things."

But a full calendar is not the same as a useful day.

Randy Pausch, the Carnegie Mellon professor best known for The Last Lecture, gave a famous talk on time management that included his adaptation of the Eisenhower/Covey Matrix. The model is simple: sort work by two questions.

  • Is it important?
  • Is it urgent?

That gives you four buckets.

%%{init: {"theme": "base", "themeVariables": {"background": "transparent", "primaryTextColor": "var(--md-default-fg-color)", "secondaryTextColor": "var(--md-default-fg-color)", "tertiaryTextColor": "var(--md-default-fg-color)", "fontFamily": "Clarity City, sans-serif", "lineColor": "var(--md-default-fg-color--lighter)", "quadrant1Fill": "rgba(239, 68, 68, 0.18)", "quadrant1TextFill": "var(--md-default-fg-color)", "quadrant2Fill": "rgba(34, 197, 94, 0.18)", "quadrant2TextFill": "var(--md-default-fg-color)", "quadrant3Fill": "rgba(245, 158, 11, 0.18)", "quadrant3TextFill": "var(--md-default-fg-color)", "quadrant4Fill": "rgba(100, 116, 139, 0.18)", "quadrant4TextFill": "var(--md-default-fg-color)", "quadrantPointFill": "var(--md-accent-fg-color)", "quadrantPointTextFill": "var(--md-default-fg-color)", "quadrantXAxisTextFill": "var(--md-default-fg-color)", "quadrantYAxisTextFill": "var(--md-default-fg-color)", "quadrantInternalBorderStrokeFill": "var(--md-default-fg-color--lightest)", "quadrantExternalBorderStrokeFill": "var(--md-default-fg-color--lighter)", "quadrantTitleFill": "var(--md-default-fg-color)"}}}%%
quadrantChart
    title The Eisenhower/Covey Time Management Matrix
    x-axis Not Urgent --> Urgent
    y-axis Not Important --> Important
    quadrant-1 Do It Now
    quadrant-2 Schedule It
    quadrant-3 Delegate It
    quadrant-4 Do Not Do It
    "Crisis deadline": [0.86, 0.86]
    "Family emergency": [0.76, 0.78]
    "Weekly plan": [0.22, 0.86]
    "Exercise": [0.18, 0.72]
    "Skill practice": [0.34, 0.66]
    "FYI meeting": [0.74, 0.34]
    "Low-value ping": [0.84, 0.22]
    "Feed refresh loop": [0.18, 0.12]

Task: A Practical Guide to Cross-Platform Build Automation

Task

make is still one of the most useful tools in a developer's toolbox, but a lot of modern repositories need something more portable, more readable, and easier to share between local development and CI. Task is a fast, cross-platform task runner that keeps the good part of a Makefile, one command for common project workflows, while replacing the rough edges with a YAML-based Taskfile.yml, built-in dependency orchestration, variables, templating, caching, and solid behavior on Windows, macOS, and Linux.

Field Dispatch: The First ESX Host Drifts from Custom Certificates After VMware Cloud Foundation 9 Instance Bring-Up

Affected Versions

  • VMware Cloud Foundation 9.1.x.x
  • VMware Cloud Foundation 9.0.x.x

If you're using securitySpec to deploy VMware Cloud Foundation 9.x with external CA-signed ESX certificates, the bring-up can look successful while still leaving you with one surprise:

Post Deployment Configuration Drift

The first ESX host will be deployed with a VMCA-signed certificate instead of the external CA-signed certificate provided.

I ran into this while testing external CA-signed certificates through both the API and Ansible. The JSON payload was accepted and the instance bring-up completed. Every ESX host kept its external CA-signed certificate except the first one, the host used to bootstrap the vCenter appliance.

Tip: Using the GitHub CLI to Copy Labels Between Repositories

Tip

If you manage multiple GitHub repositories and want consistent labels, drift happens quickly.

Use GitHub CLI to run gh label clone and copy a source repository's labels into a destination repository.

If gh isn't installed yet, install it first:

brew install gh
sudo apt update && sudo apt install -y gh
# RHEL
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
sudo dnf install -y gh

# Fedora
sudo dnf install -y gh
winget install GitHub.cli

Then authenticate:

gh auth login
gh auth status

That second command is worth running. It confirms that your session is active before you try to modify repository settings.

Clone Labels into the Current Repository

If you're already in the destination repository directory, the command is simple:

gh label clone OWNER/SOURCE-REPO

Example:

gh label clone tenthirtyam/example

That copies every label from tenthirtyam/example into the current repository.

Target a Different Destination Repository

If you aren't inside the destination repository, use --repo:

gh label clone OWNER/SOURCE-REPO --repo OWNER/DESTINATION-REPO

Example:

gh label clone tenthirtyam/source-example --repo tenthirtyam/destination-example

What Randy Pausch's The Last Lecture Still Teaches Us Still

Some books comfort you. Others hold up a mirror.

The Last Lecture by Randy Pausch does a little of both.

Pausch was a computer science professor at Carnegie Mellon University. In 2006, he was diagnosed with pancreatic cancer. By September 18, 2007, after learning the cancer had returned and that he had only months left to live, he gave his now-famous lecture, "Really Achieving Your Childhood Dreams."

The talk became a book, but the real reason it endures is simpler than its title suggests:

It's not about dying. It's about how to live while you're still here.

That distinction matters. A lot of writing about mortality becomes soft around the edges. Pausch did something better. He stayed funny, practical, and honest about disappointment, work, family, and the ways adults drift from what once made them feel alive.

Today, him words feel especially clarifying because modern life is crowded with noise. We optimize calendars, answer messages at red lights, and confuse urgency with importance. We get very efficient at moving and very unclear about where we are going.

Pausch's voice cuts through that. He keeps asking a hard, useful question:

What would you do differently if you stopped pretending you had unlimited time?

Ubuntu 26.04: How to Upgrade from 24.04 LTS

Ubuntu 26.04 LTS Resolute Raccoon

Ubuntu 26.04 LTS, Resolute Raccoon, was officially released on April 23, 2026.

If you're like me and want to upgrade now, here's a clean step-by-step process to do it on both Ubuntu Desktop and Ubuntu Server.

Before the Upgrade

Before you begin the upgrade, review the following checklist.

  1. Back up anything you care about.
  2. If the system is a VM, take a snapshot.
  3. Make sure the current 24.04 LTS install is fully patched.
  4. Make sure you have enough free disk space.
  5. Be prepared to answer interactive prompts during the upgrade.

On Ubuntu Server, I'd also review any third-party repositories or PPAs before you start. They are a common source of upgrade friction, and Ubuntu may disable them during the release upgrade anyway.

Update the current system first:

sudo apt update
sudo apt dist-upgrade -o APT::Get::Always-Include-Phased-Updates=true
sudo reboot