Skip to content

Releases: ixjosemi/Moonglade

Moonglade 0.2.2

Choose a tag to compare

@ixjosemi ixjosemi released this 10 Aug 11:59
ed82809

The app icon, the site favicon and the README banner now share one moon — the hero photograph's, rather than three drawn approximations of it.

Install or update:

curl -fsSL https://github.com/ixjosemi/Moonglade/releases/latest/download/install.sh | sh

Moonglade 0.2.1

Choose a tag to compare

@ixjosemi ixjosemi released this 10 Aug 10:00
239f7ac

First release built and signed by the release workflow, and the first with installable assets attached.

curl -fsSL https://github.com/ixjosemi/Moonglade/releases/latest/download/install.sh | sh
  • A curl installer that verifies the download against SHA256SUMS, wires the agent hooks and launches the app.
  • The build is signed with a stable self-signed identity, so the automation permission that focuses your terminal survives updates. It is not notarized.
  • A landing page at https://ixjosemi.github.io/Moonglade/, which serves that same installer at /install.

v0.2.0 carried no assets: it was tagged before the workflow that produces them existed.

Moonglade 0.2.0

Choose a tag to compare

@ixjosemi ixjosemi released this 10 Aug 06:58
v0.2.0
1bfe6f4

Twenty-four commits since 0.1.0. Almost all of them are corrections, and they concentrate in the two places where a wrong answer is worse than no answer: which terminal pane a session actually lives in, and whether the notch is telling you the truth about who is waiting for you.

Sessions find their pane

Ghostty's scripting bridge exposes only a surface id, name and working directory — no PID, no TTY — so several agents in one project directory left the matcher nothing to tell their panes apart. It fell back to enumeration order and then froze that guess for the life of the app: a session could adopt a pane running caffeinate -di and keep its name and its focus target for hours.

  • Agents that name their sessions now say so. The OpenCode plugin reports the session name as session_title; that equality identifies the pane, names the row without scraping a terminal at all, and aims focus when no surface id was resolved.
  • Identity is separated from inference. Only PID, TTY, session title, or a title that singles the tool out is remembered; a pane picked by enumeration order is a guess the next scan re-evaluates, and a pane whose title reads as another command is never claimed.
  • When nothing tells two panes apart, they pair by age instead of process ID — the kernel wraps its numbering, so the oldest session on a machine can hold the highest PID.
  • Sessions started inside Claude for Desktop have no TTY or surface identity and always failed focus with missingTerminalTarget. They are now detected through process ancestry and focused by bundle id (#18, fixing #15).
  • cmux identity moved to CMUX_SURFACE_ID, the variable cmux documents as canonical, off the legacy CMUX_PANEL_ID alias (#13).

The bar tells the truth

  • A blocked session stays red in the bar until you actually answer it. It used to downgrade to the quiet waiting state as soon as its tab came frontmost, so a pending permission showed red in the menu and green in the bar. The entire acknowledgment subsystem behind that — including a two-second AppleScript poll of Ghostty — is gone; bar and menu now compute the semaphore from the same state.
  • OpenCode's AskUserQuestion prompts count as needing attention. OpenCode 1.18 emits question.asked / question.replied / question.rejected, and the plugin only handled permission events, so a session waiting on an answer kept showing as working.
  • A permission prompt raised inside a subagent turns the root session red. Child-session events were dropped wholesale even though the prompt blocks you in the root terminal; a per-root ledger keeps the root marked until the last outstanding prompt is answered.
  • A bar showing only the red blocked semaphore no longer hangs a one-sided silhouette.

The menu

  • The inline action list resolves its highlight from the pointer position on every hover sample, so highlights stop trailing the pointer during the expansion spring, and the list keeps a single hover selection.
  • The rename field and the kill confirmation drop their flat boxes for the panel's glass language: hairline field that wakes on focus, capsule verdict buttons with red glass for the destructive one. The rename placeholder is legible on dark glass.

The installed app

  • An installed Moonglade.app loaded its Metal shader out of the developer's .build tree and trapped on launch the moment that tree moved. It now resolves its resource bundle beside the installed binary, and a missing shader disables the ripple instead of crashing (#14).
  • moonglade doctor recognises a Codex notify hook reached through another tool's chain, and points at what actually unblocks you instead of offering an install that would refuse to run.

A new icon

A moonglade is the streak of moonlight water throws back at you, so the icon is now the moon and its reflection and nothing else — a frosted body over a sheet of glass seen edge-on. The old notch-and-crescent said nothing about the product and read as do-not-disturb. The icon build now fails when the rasterizer silently drops the SVG blur filters the glass is made of.

Performance and runtime hardening

  • Idle CPU down 58%, with no change to rendering (#12), and the notch's pointer containment check coalesced so it stops rerunning once per frame for the length of every open and close spring.
  • Every state-directory mutation is serialised. Only save() took the write lock, so a reaper removal could race a hook process writing the same document; POSIX record locks alone could not have covered it, since they are held per process.
  • Released observation schedulers cancel their directory watchers instead of leaking one file descriptor per watched directory.
  • The scanner's ancestor walk no longer re-reads command lines from the kernel on every tick, and overlays for Convoy-owned sessions survive orphan pruning.
  • CI fails when Ripple.metal changes without regenerating the committed metallib, which previously shipped the stale shader silently.

Thanks

This release exists partly because people outside the repo took the time to file and fix things:

  • @diesektfuture777 — the installed app's shader bundle resolution (#14) and the move to cmux's canonical surface variable (#13). Both landed with the reasoning written down, which is why they were easy to merge.
  • @KesleyDavid — focus for sessions hosted by the Claude desktop app (#18).
  • @FethiOmur — reported #15, the bug behind that fix, with the detail needed to reproduce it.

Install

This release is source-only — there is no signed or notarized binary, so there is nothing here to download and run. Build it:

git clone https://github.com/ixjosemi/Moonglade.git
cd Moonglade
./scripts/install.sh

One command builds the app, installs it into /Applications, wires the agent hooks, launches it, and verifies the result. The same command reinstalls. Verify at any time with moonglade doctor.

Requires macOS 14 Sonoma or newer (macOS 26 for the real Liquid Glass backdrop), Swift 6.0 to build, and a notched MacBook for the intended placement. Apple Silicon is the tested platform; Intel is not yet validated.

Privacy

Unchanged: no networking, no telemetry, no accounts, no third-party Swift dependencies. Session metadata stays in ~/.moonglade/state with user-only permissions, and prompts and model responses are never stored. See PRIVACY.md.

Known limitations

  • Still no signed or notarized binary, no automatic updater, no Homebrew cask.
  • Codex rollout formats are not a stable contract; unknown lines are ignored and the notify hook remains the reliable turn-complete signal.
  • Panes that share a project directory and offer no distinguishing title are paired by creation order. That is a guess, it is re-evaluated on every scan, and it is never remembered.

Full changelog: v0.1.0...v0.2.0

Moonglade 0.1.0

Choose a tag to compare

@ixjosemi ixjosemi released this 25 Jul 13:42
v0.1.0
a3adba3

Moonglade is a quiet, native macOS indicator for Claude Code, OpenCode, Codex CLI, Pi, and Convoy sessions. It lives around the MacBook notch — a pill on displays without one — and returns you to the exact terminal tab or tmux pane with one click.

What it does

  • Global counts for running, waiting, and blocked sessions, without inferring them from provider icons.
  • Click the summary and a wide session menu grows out of the notch: provider, status light, session title from the live terminal tab, project directory, git branch (worktrees included) or Convoy pipeline step, and elapsed time.
  • One click focuses the recorded Ghostty, cmux, iTerm2, Terminal, or tmux session.
  • Expand a row for inline actions: rename, copy the project path, reveal in Finder, kill the process — SIGTERM escalating to SIGKILL — or close its exact tmux pane or Ghostty tab.
  • Convoy pipeline runs are first-class sessions: current step in the row, red light on human gates, no duplicate rows for the OpenCode sessions a pipeline owns.
  • Closed terminals disappear immediately through kernel exit notifications, with a five-second scanner and reaper backstop.

Everything is event-driven and off the main thread: a libproc scanner at ~2 ms per sweep on a five-second heartbeat, EVFILT_PROC exit watchers, and debounced directory observation. Idle cost is roughly 1% CPU and 16 MB.

Privacy

No networking, no telemetry, no accounts, no third-party Swift dependencies. Session metadata stays in ~/.moonglade/state with user-only permissions. Prompts and model responses are never stored. See PRIVACY.md.

Install

This release is source-only — there is no signed or notarized binary, so nothing here to download and run. Build it:

git clone https://github.com/ixjosemi/Moonglade.git
cd Moonglade
./scripts/install.sh

One command builds the app, installs it into /Applications, wires the agent hooks, launches it, and verifies the result. The same command reinstalls. Verify at any time with moonglade doctor.

Requires macOS 14 Sonoma or newer (macOS 26 for the real Liquid Glass backdrop), Swift 6.0 to build, and a notched MacBook for the intended placement. Apple Silicon is the tested platform; Intel is not yet validated.

Known limitations

  • No signed or notarized binary, no automatic updater, no Homebrew cask.
  • Codex rollout formats are not a stable contract; unknown lines are ignored and the notify hook is the reliable turn-complete signal.
  • Same-directory Codex sessions can be ambiguous when upstream events carry no PID or terminal identifier.