Agent Notch puts a walking mascot in your MacBook notch and clears it when the terminal regains focus
The open-source alternative to vibe-island
At a glance
- What is it?
- Agent Notch is a single-file Swift program that shows whether Claude Code or Codex is working without any hooks, APIs, or accounts. It polls the process table and the agents' own transcript files every three seconds, which buys zero configuration at the cost of a documented lag: the mascot keeps walking for roughly 33 seconds after a turn actually ends.
- Who is it for?
- Agent Notch fits someone running several Claude Code or Codex sessions in terminals who wants peripheral awareness without watching them, since the notification model, the session panel, and the click-through bar all cost nothing to configure. It does not fit anyone who needs to know the instant a turn ends, because the busy and idle inference is a 30 second window over bursty transcript writes and the documented fix is agent hooks the project deliberately skipped.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 72 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Liveness comes from ps, lsof, and transcript writes every 3 seconds
The design constraint is stated up front: no hooks, no APIs, no accounts. Liveness detection follows the model of open-vibe-island, where a session is defined as a running agent process in a terminal, and it is polled every three seconds.
Three mechanisms produce the state. `ps` finds `claude` and `codex` processes attached to a TTY, which is why headless and background sessions are ignored: no terminal, no notch. `lsof` then maps each process to the file it holds open, which is the transcript for Codex and the working directory for Claude Code, since Claude Code does not keep the transcript file descriptor open. The transcripts themselves supply the metadata: prompts, snippets, models, and subagents.
The transcript locations are specific. Claude Code writes to `~/.claude/projects/*/*.jsonl`, with subagents under `<session>/subagents/agent-*.jsonl`. Codex writes to `~/.codex/sessions/**/*.jsonl` and is grouped by `parent_thread_id`, which is how its subagents are reassembled into the right parent session.
Nothing is being asked of the agent, which is what makes installation a single command with no configuration file to author.
Claude Code is found by working directory, Codex by its open transcript
The `lsof` step is where the two agents genuinely differ, and the difference is a file descriptor, not a preference.
Codex keeps the transcript open, so the mapping is direct: the open file descriptor names the session's JSONL. Claude Code does not keep the transcript fd open, so the fallback is its working directory, and the session has to be identified from that path instead. Anyone extending this to another agent should expect to answer the same question for each one: does this tool hold its session file open while it runs?
The second detail is the TTY requirement. Because discovery starts from `ps` matching processes attached to a terminal, an agent running headless, in CI, or detached from a terminal produces no mascot. That is deliberate rather than a gap: the notch is a view of the terminal you are looking at, not a global agent monitor.
Metadata extraction then runs against the JSONL files. Prompts become the row titles, snippets fill in detail, the model tag comes from the session file rather than from your configuration, and subagents are enumerated from the nested files, which is how the panel can show a count before you open it.
Busy means a transcript write in the last 30 seconds
Within a live session, busy and idle is described as a hybrid rather than a flag. A process that is alive with a transcript written in the last 30 seconds is busy, and that is what makes the mascot walk. A process that is alive but quiet is idle, which shows nothing in the notch and a dimmed row in the panel.
Finished is inferred from absence instead: a process gone for two polls is done, and its mascot becomes a green blob. Two polls at a three second interval means roughly six seconds of grace before a finished agent is marked as such.
The green state carries a meaning that is separate from done, and it is the most interesting detail in the project. Green means finished since you last looked. Activating a terminal application, from a list that includes Ghostty, Terminal, iTerm2, kitty, Warp, and Alacritty, acknowledges the finished agents and clears their indicator. So the notification survives exactly as long as you have not looked at the terminal where the work happened.
There is also a retention rule: sessions idle for more than six hours drop off the panel entirely, which keeps the list from becoming an archive of every session you have ever started.
The mascot keeps walking for up to about 33 seconds after a turn ends
The project documents its own flaw with a name: the roughly 30 second afterglow.
The cause is that busy and idle are inferred from transcript write times, and transcript writes are bursty. A turn emits several writes and then goes quiet, so the 30 second window keeps the mascot walking for up to about 33 seconds after the turn actually finishes, which is the 30 second window plus the 3 second poll. In the other direction, a quiet stretch inside a long turn is smoothed over, so a genuinely busy agent can look idle.
The stated conclusion is that no process level proxy can fix this, because network activity, CPU use, and child processes are all indirect, and only the agent knows when its turn ends.
The precise fix would be agent hooks, specifically `UserPromptSubmit` and `Stop` writing a state file, which is what open-vibe-island does. That was deliberately skipped here to keep the zero-config, no-hooks design, and the documentation names it as the upgrade path if the afterglow is unacceptable.
The transparency of the result is stated just as plainly: the indicator can be wrong for half a minute, and if you need it to be right, you are meant to change the design.
The pet is one file you overwrite, with eight choices
The Codex animation uses the official Codex Pets spritesheets, kept in the `pets/` directory of the repository, and switching between them is a shell redirect rather than a settings window.
echo dewey > ~/.config/agent-notch/petThe available names are `codex`, `dewey`, `fireball`, `rocky`, `seedy`, `stacky`, `bsod`, and `null-signal`. The change takes effect within a couple of seconds and needs no restart, which is the payoff of storing the choice as the contents of a file rather than in a preferences database.
Attribution is explicit: the spritesheets are marked as OpenAI's, taken from their public pets CDN. So the artwork is not part of this project's licence, and the project's own MIT licence covers the code rather than the characters.
For Claude, the mascot is different in kind: the Claude Code banner critter, rather than a swappable sprite set. The per-slot behaviour is the same, so a Claude session and a Codex session occupy separate positions beside the notch, and one finishing does not disturb the other still running.
The panel shows one row per session, titled by your prompt
Clicking the indicator opens the panel, and the design rule is that a row belongs to you rather than to the agent. One row per session, titled by the tool, led by your latest prompt, not the agents' chatter.
That single decision is what makes the list readable during a long run, since a transcript is mostly assistant output and one line of user intent is what you would recognise.
Subagents are folded rather than listed. Codex's philosopher swarm and Claude's Task agents collapse under a `▸ N subagents` dropdown, so a session that spawned twelve helpers still occupies one row. Running rows show their mascot walking in place, finished rows carry a green pixel checkmark, and idle rows are dimmed.
The tag on the right of each row is the actual model that session runs, read from the transcript rather than from a setting. That distinction matters when you have several sessions open with different models, because a row telling you the model is the reason you can tell them apart at a glance.
Clicking anywhere closes the panel. The collapsed window itself is transparent and click-through except for the small indicator zone, so it never blocks menu bar items or the apps underneath, and in a fullscreen space the bar spans the entire top edge.
It builds with one swiftc command and installs as a Login Item
There is no package manager and no dependency file. The repository is a single `main.swift` with a `pets/` directory and documentation, and it compiles with one command:
swiftc -O main.swift -o AgentNotch
./AgentNotch &That is the whole build. There is nothing to install first, which is the same property that makes the zero-config design possible at runtime.
Starting at login is a manual step rather than a feature: open System Settings, go to General, then Login Items, and add `AgentNotch`. There is no launch agent file, no installer, and no preference pane, so a machine you set up by hand needs a minute of manual configuration after the first build.
Requirements are macOS 12 or newer, and the caveat is stated plainly: it is built and tested on a notched MacBook, and on a notchless display it centres itself on a virtual notch. So on a desktop Mac or an external monitor the indicator will sit in the middle of the top edge rather than beside a cutout.
Interaction is minimal by design: click the indicator to open the panel, click anywhere to close it.
Editorial conclusion
Agent Notch fits someone running several Claude Code or Codex sessions in terminals who wants peripheral awareness without watching them, since the notification model, the session panel, and the click-through bar all cost nothing to configure. It does not fit anyone who needs to know the instant a turn ends, because the busy and idle inference is a 30 second window over bursty transcript writes and the documented fix is agent hooks the project deliberately skipped. Before adopting it, read the known limitation rather than the screenshots, and remember the spritesheets are OpenAI's Codex pets, the whole thing is one `main.swift`, and it needs macOS 12 or newer.
Frequently asked questions
How does Agent Notch know an agent is running?
It polls every 3 seconds with no hooks, APIs, or accounts. ps finds claude and codex processes attached to a TTY, lsof maps each to its transcript or working directory, and transcripts in ~/.claude/projects and ~/.codex/sessions supply prompts, models, and subagents.
Why does the mascot keep walking after Claude Code or Codex finishes?
Busy and idle are inferred from transcript write times with a 30 second window, and transcript writes are bursty, so the mascot can keep walking for up to about 33 seconds after a turn ends. The documented fix is agent hooks writing a state file, which was skipped to keep the design hook-free.
How do I change the Agent Notch pet?
Write the name to ~/.config/agent-notch/pet, for example echo dewey > ~/.config/agent-notch/pet. The options are codex, dewey, fireball, rocky, seedy, stacky, bsod, and null-signal, and the change takes effect within a couple of seconds with no restart.
How do I build and run Agent Notch?
Compile the single Swift file with swiftc -O main.swift -o AgentNotch and run ./AgentNotch in the background. macOS 12 or newer is required, and to start at login you add AgentNotch through System Settings, General, then Login Items.
What does the Agent Notch panel show?
One row per session, titled by the tool and led by your latest prompt rather than the agents' chatter. Subagents fold under a subagents dropdown, running rows show a walking mascot, finished rows get a green checkmark, and the tag on the right is the model that session actually runs.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/realfishsam-agent-notch)