Ping Island is a macOS menu-bar app that monitors active sessions from AI coding agents and helps users return to the relevant terminal or IDE when an agent needs attention. It is for developers working with supported coding clients across multiple windows. The catalogue entry provides instructions for using those clients with the app.
Borrowing it
Nothing to install: this file belongs to erha19/ping-island. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.
curl -O https://raw.githubusercontent.com/erha19/ping-island/main/AGENTS.mdgit clone --depth 1 https://github.com/erha19/ping-islandWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/instructions/erha19/ping-island/agents-md)<a href="https://agentmods.dev/instructions/erha19/ping-island/agents-md"><img src="https://agentmods.dev/badge/instructions/erha19/ping-island/agents-md/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/instructions/erha19/ping-island/agents-md"><img src="https://agentmods.dev/badge/instructions/erha19/ping-island/agents-md.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.08609 | $0.08609 |
| Opus 5.5 | $0.03444 | $0.03444 |
| Sonnet 5.5 | $0.01722 | $0.01722 |
| Haiku 4.5 | $0.00861 | $0.00861 |
Grade B, and why
ping-island AGENTS.md scanned grade B with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 12d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Reads agent configuration directoriesmediumAgent snooping
.claude/, .codex/, .gemini/ hold keys, settings and other credentials a mod has no legitimate need for.
- Gemini CLI hooks are managed through `~/.gemini/settings.json`; its `BeforeTool` / `AfterTool` matchers are regex-based, so use `.*` rather than Claude-style `*`. How it starts
The opening of the file, as written. The whole thing — 228 lines — stays where its author put it; the contents beside it link to each section on GitHub.
AGENTS.md
This file is a routing layer for coding agents working in this repo. Keep it short. Put long-lived detail in nearby code, focused docs, or tests.
Mission
PingIslandis a macOS menu bar app that surfaces Dynamic Island-style status for Claude Code, Codex, Gemini CLI, Antigravity CLI, Hermes Agent, Qwen Code, Kimi CLI, Oh My Pi, and compatible hook-driven agent sessions.- The main runtime path is:
- hook or app-server events
- monitoring and service layers
SessionStoreSessionMonitorandNotchViewModel- SwiftUI notch UI
- There are two important codepaths:
PingIsland/: the shipping Xcode appPrototype/: a SwiftPM prototype with focused tests and reference implementations
Start Here
- Product overview:
README.md - App entry:
PingIsland/App/PingIslandApp.swift,PingIsland/App/AppDelegate.swift - Docked/detached presentation orchestration:
PingIsland/App/IslandPresentationCoordinator.swift,PingIsland/App/WindowManager.swift - First-run surface-mode onboarding and mode-switch UI:
PingIsland/App/AppDelegate.swift,PingIsland/UI/Window/SettingsWindowController.swift,PingIsland/UI/Views/SettingsWindowView.swift - Main state hub:
PingIsland/Services/State/SessionStore.swift - Session association cache:
PingIsland/Services/State/SessionAssociationStore.swift - Usage/quota snapshots for Claude status-line caches, Claude-family transcript token totals, and Codex rollout logs:
PingIsland/Services/Usage/- Claude-family transcript token totals are tailed incrementally by
ClaudeTranscriptUsageReader, which skips reopening unchanged files, rebuilds only after replacement/truncation, defers half-written trailing records, and carries a streaming FNV-1a digest soAgentUsageStorededuplication stays stable. Keep cumulative totals for the whole transcript, and do not return to whole-file reparsing for ordinary appends. - Local agent usage analytics keeps a backward-compatible per-day session token ledger for the statistics panel's latest-three-today total and current-calendar-week top session; preserve legacy
agent-usage.jsondecoding when evolving it AgentUsageTokenTotalskeeps the input tiers apart:inputis uncached input only, withcacheCreation/cacheReadalongside it. Cache reads are re-reads of context already sent, so they stay out oftotal, out ofbillableInput, and are priced at their own rate; folding them back intoinputoverstates usage by orders of magnitude on long sessions. BumpAgentUsageDocument.currentSchemaVersionwhenever stored counters change meaning, and migrate by zeroing token counters while leaving session records, tool counts, and the activity heatmap intact.- One assistant response spans several transcript lines (one per content block) that each repeat the same
message.usage;ClaudeTranscriptUsageAccumulatorcounts amessage.idonce per consecutive run. Those repeats are always adjacent, so keep this O(1) rather than introducing a seen-set that would grow with the transcript.
- Claude-family transcript token totals are tailed incrementally by
- Native runtime rollout scaffold:
PingIsland/Services/Runtime/,PingIsland/Core/FeatureFlags.swift - Session bridge for UI:
PingIsland/Services/Session/SessionMonitor.swift - Claude-family transcript titles and last-message text:
PingIsland/Services/Session/ConversationParser.swift- Missing derived Claude transcripts must not fall back to unrelated OpenClaw history. OpenClaw rotation recovery requires an explicit path in that client's sessions directory. Reload store state after awaiting transcript reads so completed or archived sessions are not restored from stale snapshots.
- Claude Code 2.x stopped writing
summaryrecords and now persists the title shown in its own UI as acustom-titlerecord, rewritten on every turn. Take the newest one, keep the legacysummarypath as a fallback for older transcripts and other Claude-compatible clients, and only fall back to the first user message when neither exists.
- Notch state and layout:
PingIsland/Core/NotchViewModel.swift,PingIsland/UI/Views/NotchView.swift - App-wide low-power policy for background polling, event monitoring, UI animation tiers, and silent update gating:
PingIsland/Core/EnergyGovernor.swift - Session-aware keep-awake:
PingIsland/Core/SessionKeepAwake.swift,PingIsland/Core/KeepAwakePolicy.swift, and behavior/verification. Use one assertion owner and one persistedkeepAwakeModeshared by the notch shortcut and settings. Auto-mode power checks must continue while work or grace exists even after low battery releases the assertion; measure the 120-second grace from the last working session stopping, not its last published activity. Always mode bypasses the battery floor and must not run a grace timer. - User idle protection for temporarily routing blocking approvals/questions back to terminals:
PingIsland/Core/UserIdleAutoProtection.swift,PingIsland/Core/Settings.swift,PingIsland/Services/Hooks/BridgeRuntimeConfigWriter.swift - Detached floating capsule:
PingIsland/UI/Window/DetachedIslandWindowController.swift,PingIsland/UI/Views/DetachedIslandPanelView.swift,PingIsland/UI/Views/IslandOpenedContentView.swift- Detached pet interactions now keep the pet anchored in place while hover/click previews expand sideways as message-bubble lists; trace both the panel layout and window-anchor math together when changing this flow
- Expanded content routing is shared with the docked notch through
IslandOpenedContentView+IslandExpandedRouteResolver; keep hover/click/notification semantics aligned instead of reintroducing detached-only content priorities
- Global shortcuts and shortcut persistence:
PingIsland/Services/Shared/GlobalShortcutManager.swift,PingIsland/Utilities/GlobalShortcut.swift,PingIsland/Core/Settings.swift,PingIsland/UI/Views/SettingsWindowView.swift - Claude hook ingress:
Prototype/Sources/IslandBridge/,PingIsland/Services/Hooks/HookInstaller.swift,PingIsland/Services/Hooks/HookSocketServer.swiftPingIslandBridgeis the unified Claude/Codex hook entrypoint and is responsible for terminal, tmux, SSH-remote, and IDE terminal context capture before envelopes hit Swift codeAskUserQuestionmust remain answerable underbypassPermissionsand session auto-approval. A question response already allows the tool withupdatedInput; never mark its tracked tool as waiting for approval, or the next hook resurrects a redundant approval card.- Claude questions intercepted at
PreToolUseneed the same long hook timeout asPermissionRequestin both local and remote installs. Only recognized question tools own that answer channel; a normal tool'squestionsargument must never turn it into an Island question. - State-only hook delivery is acknowledged by the app after envelope decoding and routing; keep bridge socket writes complete and do not report
deliveryOutcome=deliveredwithout a matching app acknowledgement
- Codex ingress:
PingIsland/Services/Codex/,PingIsland/UI/Views/CodexSessionView.swift- The desktop client is branded ChatGPT; retain the
codex-appprofile, Codex provider/CLI identifiers,com.openai.codexbundle ID, andcodex://thread links for compatibility. App-server discovery prefersChatGPT.app, keeps legacyCodex.appas a fallback, and may only launch its bundledcodexbinary after validating the canonicalcom.openai.codexapp. Other IDEs can embed a binary with the same filename; their app identity must not be applied to every Codex thread. Rolloutoriginatorstays host/source metadata and must not replace the canonical client-profile display name. - Qoder statistics variables never establish host identity. Desktop evidence beats bare IDE hints; TTY, terminal program/session, and tmux evidence preserve real Codex CLI routing. Routing repairs must replace nullable fields in both persisted associations and current memory instead of merging stale hosts back in. See Codex identity and filtering.
- Title and ambient suggestion helpers can use real project directories and execute tools. Recognize exact helper sources or dedicated opening prompts in
CodexAuxiliaryHookFilteracross hooks, app-server snapshots, rollout recovery, and restored UI rows. Never hide ordinary JSON replies or user-createdambient_suggestion_taskthreads by their output shape. - Hook-less fallback parsing for Codex sessions lives in
PingIsland/Services/Codex/CodexRolloutParser.swift - The fallback parser tails append-only rollout JSONL incrementally, rebuilds after file replacement/truncation, skips pathological oversized records, and retains a bounded recent history. Keep the full content of each retained item, and do not return to whole-file reparsing for ordinary appends.
- App-server
thread/listrows are canonicalized by thread ID before ingestion. Keep active/newer/readable rollout candidates preferred, keep rollout recovery cache keys path-scoped, and discard the old parser cache only when the canonical rollout path genuinely changes.
- The desktop client is branded ChatGPT; retain the
- Terminal and focus control:
PingIsland/Services/Tmux/,PingIsland/Services/Window/,PingIsland/Utilities/TerminalVisibilityDetector.swift- Terminal focus flows currently cover iTerm2, Ghostty, Terminal.app, tmux, and IDE-hosted terminals
- Sessions hosted inside the Claude desktop app are focused by tab, not by app:
PingIsland/Services/Session/ClaudeDesktopSessionIndex.swiftmaps the hooksession_id(the CLI session id) to the desktop-sidelocal_…id recorded in~/Library/Application Support/Claude/{claude-code-sessions,local-agent-mode-sessions}/<org>/<account>/local_*.json, andSessionLauncheropensclaude://claude.ai/epitaxy/<local id>(the app's own session route;/code/<id>reloads the page and lands on the last-focused tab since Claude 1.46). Theclaude://code/continue?session=…entry link is a server-gated surface and cannot be relied on
- Remote SSH forwarding and remote-host management:
PingIsland/Services/Remote/- Remote hosts can bootstrap a bridge on the SSH target, rewrite remote hooks, install managed plugin-directory integrations such as Hermes under the remote home directory, and attach a bidirectional forwarding channel back into PingIsland
- The remote bridge forwards recent Codex app-server thread activity from the SSH target's
~/.codex/state_*.sqlitethrough the existing remote hook-event channel
- Provider/client routing: bridge envelopes are normalized in
PingIsland/Services/Hooks/HookSocketServer.swift, stored onSessionState, and launched viaPingIsland/Services/Window/SessionLauncher.swift- IDE host names mirrored into
client_originatorand terminal bundle IDs describe the terminal surface, not the agent. Keep them out of runtime client matching; generic Claude hooks must retain a concreteclaude-codeprofile so fresh events can correct stale client associations.
- IDE host names mirrored into
- Client profile registry: installable hook clients and runtime client branding / recognition are centralized in
PingIsland/Models/ClientProfile.swift- The Kimi desktop app is a separate target (
kimi-app-hooks). It runs a vendored kimi-code kernel (@moonshot-ai/agent-core) out of~/Library/Application Support/kimi-desktop/daimon-share/daimon/runtime/kimi-code/config.toml, so chat and agent turns both speak the same hooks protocol as the CLI. That file is rewritten every time Kimi's daimon runner starts, which drops the managed block;KimiAppHookGuardis started/stopped bySessionMonitor, polls it and reinstalls whenever the block goes missing; failed writes must stay retryable even if the file timestamp is unchanged. Sessions from this target carry--client-kind kimi-appso they resolve to thekimi-appruntime profile and badge as "Kimi App".
- The Kimi desktop app is a separate target (
- VS Code-compatible IDE focus extension install / URI launch:
PingIsland/Services/Window/IDEExtensionInstaller.swift,PingIsland/Services/Window/TerminalSessionFocuser.swift - Session list UI:
PingIsland/UI/Views/SessionListView.swift - Client mascot system:
PingIsland/UI/Components/MascotView.swift,PingIsland/UI/Views/MascotSettingsView.swift - App updates and release notes:
PingIsland/Services/Update/,PingIsland/UI/Views/ReleaseNotesWindowView.swift,PingIsland/UI/Window/ReleaseNotesWindowController.swift - Sparkle build configuration:
Config/App.xcconfig,Config/LocalSecrets.xcconfig,docs/sparkle-release.md - Mac App Store distribution lane:
PingIslandAppStoretarget / scheme,PingIsland/Info-AppStore.plist,PingIsland/Resources/PingIsland-AppStore.entitlements,Config/AppStore.xcconfig,scripts/build-app-store.sh, anddocs/mac-app-store-submission.md
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 12d ago Changed · -2 lines · -127 tokens per session fa0d3b3aba68
- 14d ago Changed · +3 lines · +197 tokens per session cb83c95eeeba
- 1mo ago Changed · +2 lines · +178 tokens per session 158f53ac86cd
- 1mo ago Changed · +5 lines · +319 tokens per session 2f9225b48468
- 1mo ago Changed · +2 lines · +204 tokens per session 1bbcbb0cfeb5
- 1mo ago Changed · +1 lines · +56 tokens per session a761fc2e0764
- 1mo ago Changed · +2 lines · +143 tokens per session 555e7fe151a6
- 1mo ago Changed · +1 lines · +116 tokens per session 1fa2d5106103
- 1mo ago Changed · +1 lines · +73 tokens per session 28e984d89283
- 1mo ago First seen · 213 lines · 7,450 tokens per session scan B 60f945e7f44f
ping-island AGENTS.md is an instructions file published in the GitHub repository erha19/ping-island (1,138 stars, last pushed 12d ago), licensed Apache-2.0. It adds 8,609 tokens to every session, about $0.0344 per session on Opus 5.5. A static security scan graded it B with 1 finding (reads agent configuration directories). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other instructions, from other repositories
vibe-coding-prompt-template backend.instructions.md
Instructions for KhazP/vibe-coding-prompt-template: Read AGENTS.md, agentdocs/techstack.md, and agentdocs/codepatterns.md.
vscode buildNext.instructions.md
Working notes and architecture documentation for the new esbuild-based build system in build/next. Use when making changes to the new build pipeline (transpile/bundle commands, NLS plugin, source-map handling, resource copying, or self-hosting watch tasks).
next.js AGENTS.md
AGENTS.md instructions for vercel/next.js, covering next.js development guide, codebase structure, monorepo overview, core package: packages/next and other important packages.
vscode oss-third-party-notices.instructions.md
Instructions for microsoft/vscode, covering vs code oss third-party-notices pipeline, architecture, pipeline flow in ci, cache eligibility and rollout and applying the notice (cutover).
langchain AGENTS.md
AGENTS.md instructions for langchain-ai/langchain, covering global development guidelines for the langchain monorepo, corridor security analysis, project architecture and context, monorepo structure and development tools & commands.
vscode copilot-instructions.md
Copilot instructions for microsoft/vscode, covering vs code copilot instructions, project overview, root folders, core architecture (src/ folder) and built-in extensions (extensions/ folder).