Skip to content

About

Native macOS notification banners for Codex and Claude, powered by peon-ping.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Frost Notifications

Native macOS notification banners for Codex and Claude, built on peon-ping.

Readable chat titles, quiet glass, subtle doodles, and a little color. Parallel chats can each notify—even while their app is focused.

Dark Light
Codex banner with a synthetic chat title Claude banner with a synthetic chat title
  • Native app icon, project context, two-line chat title, and clear completion/input status.
  • System light/dark appearance, random color tints, and doodles, contours, or grain.
  • Short entrance/exit animations and a thin lifetime indicator; bounded hover pause.
  • Compact Took 2m 14s completion detail when timing is available.
  • Click to open the matching chat when a local mapping exists, otherwise focus its app.
  • Optional durable delivery: five visible cards, queued overflow, priority for input, and one completion sound per burst.
  • Local recent-notification history. No analytics or hosted service.
  • Respects Reduce Motion, Reduce Transparency, and Increase Contrast.

Requirements

  • macOS 13+; Apple silicon and Intel paths are supported. Native UI testing has been performed on Apple silicon.
  • peon-ping installed and working. Frost was developed against 2.37.0; run the compatibility doctor after upgrades.
  • Python 3.9+ with the standard-library sqlite3 module and SQLite JSON support. No Python packages or standalone SQLite CLI are required.
  • Compatible Codex/Claude lifecycle hooks. App metadata and hook formats can change between releases.

Frost is a Peon extension. It does not include Peon, app binaries, or sound packs. Your existing Peon sound and volume choices are retained.

Install

Choose a checkout location you can keep: the installation links to its source files.

git clone https://github.com/Akrabut/frost-notifications.git "$HOME/.local/share/frost-notifications"
cd "$HOME/.local/share/frost-notifications"
bash install.sh

This selects the glass overlay, top-right position, and one display. It preserves your dismiss time and sound settings. Keep the checkout in place while installed.

Claude: install Peon's Claude hooks first, then redirect those existing commands through Frost's bridge:

python3 claude/install-hook.py

The helper preserves unrelated hooks, matchers, timeouts, and asynchronous execution. It does not create missing Peon registrations.

Shared delivery and history:

python3 install-delivery.py

This installs the dispatcher and Codex bridge, adds Frost Recent Notifications to macOS Services, and enables delivery after installation succeeds. The default Services shortcut is Control–Option–Command–N; app shortcuts can conflict.

Codex: merge the three event arrays from codex/hooks.json into your existing Codex hooks file. Preserve unrelated entries. Review and trust the new commands through Codex's hook UI. Use SessionStart, Stop, and PermissionRequest; avoid duplicate Peon notify or subagent registrations. The delivery installer places the bridge at $CODEX_HOME/peon-hook.sh, or $HOME/.codex/peon-hook.sh by default. Frost does not write Codex trust hashes.

Verify compatibility, then finish a real turn in each app you use:

bash install.sh --doctor

The doctor opens no windows. bash install.sh --doctor --render explicitly shows a short visual preview. A successful process exit cannot prove click-to-chat navigation; test that with a real banner.

Custom locations

CLAUDE_PEON_DIR overrides Peon's directory. Otherwise Frost uses ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/hooks/peon-ping. CLAUDE_CONFIG_DIR and CODEX_HOME select the corresponding app data locations. claude/install-hook.py --settings /absolute/path/settings.json can target a particular Claude settings file.

Those environment overrides must also reach the desktop app's hook processes. Exporting them only in the installation shell does not configure an app launched from Finder. Generated installation records and the history Service contain resolved local paths; keep those private. Before moving an installed checkout, uninstall from its old location, then move it and install again. Ownership records intentionally reject a different source path. If the Python interpreter used during installation is replaced or removed, rerun the delivery installer to refresh the history Service.

Appearance and lifetime

Edit frost.json inside Peon's directory. This example matches the larger, doodled previews:

{
  "scale": 1.1,
  "tint": "random",
  "appearance": "system",
  "pattern": "doodles"
}

scale: 1 is a nominal 440×128 pt card; large scales shrink when needed to fit five slots. Patterns: doodles, contours, grain, random, or none. Appearance: system, light, or dark. Tint: random, session, none, or a named shade (ocean, plum, forest, ember, and others). Optional margin and edge_anchor: "visible" adjust placement.

PEON_FROST_SCALE, PEON_FROST_TINT, PEON_FROST_PATTERN, PEON_FROST_APPEARANCE, PEON_FROST_MARGIN, and PEON_FROST_EDGE_ANCHOR override those preferences for a process.

Peon controls ordinary lifetime; for example, peon notifications dismiss 8 selects eight seconds (0 stays until dismissed). Frost's owned delivery gives input/approval cards thirteen seconds. Hover can pause a card for up to 1.5 seconds total. The renderer itself does not play audio; delivery uses your configured Peon pack and volume.

History and recovery

From the checkout:

python3 frost recent
python3 frost resume

Recent history contains up to twenty shown labels and timestamps. Delivery runs on demand, without an always-on daemon. A later eligible hook or resume recovers queued work; pending items expire after ten minutes. Sound follows a confirmed visible banner; a crash immediately before audio launch can lose a reserved sound.

Privacy and limitations

Frost reads local chat metadata to resolve names and navigation. An unnamed chat can use a shortened opening-prompt label. Labels, links, pending records, and recent history remain on your machine. Debug logs and screenshots can contain chat text: see privacy and stored data before sharing diagnostics.

  • Response ready means the main turn ended, not that every background task succeeded. Claude completion is suppressed while reported background work remains active.
  • Duration is optional elapsed time. Claude measures observed prompt-to-Stop time, including waits. Codex uses a matching native completion record when it is available. Missing or invalid timing stays hidden; queued display time is excluded.
  • Saved names take priority. Codex can show a generated UI name that has not been saved; its local description fallback may differ. Unknown chats never borrow another chat's label.
  • Chat navigation depends on private app metadata and routes; app upgrades can require adjustments. CLI-only or ambiguous sessions may open the app instead of a chat.
  • The durable route supports desktop glass delivery. Terminal origins, non-glass/sound-only modes, active Focus/headphone/meeting controls, custom label preemptors, and advanced pack features use stock Peon behavior and its delivery limits.

Uninstall

From the same checkout, disable delivery before removing the overlay:

python3 install-delivery.py --uninstall
python3 claude/install-hook.py --uninstall
bash install.sh --uninstall

Remove only the Codex hook entries you added. The uninstallers restore owned unchanged artifacts and preserve later edits. They do not erase notification history or your remaining preferences. See privacy and stored data for private data locations.

Contributing

Run bash scripts/test.sh for the nonvisual fixture suite. It does not install Peon or edit your app settings. Native UI and Services checks are separate, explicit opt-ins; see contributing.

License

MIT. Upstream attribution is retained in NOTICE. This is an independent project, unaffiliated with OpenAI or Anthropic.

About

Native macOS notification banners for Codex and Claude, powered by peon-ping.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages