Watching one coding-agent session is easy. Watching six of them through one menu-bar icon is a compression problem.
A process list can tell you that Claude Code or Codex still exists. A file watcher can tell you that bytes changed. Neither tells you which thread needs a reply, which one is still producing output, or whether the completion marker belongs to a child agent.
The monitor has to classify each thread first. Only then can it choose one provider-level status.
The filesystem is not a session model. Claude Code can keep active and historical transcripts in different locations. Codex can retain both live and archived copies. Claude Desktop may expose the same CLI conversation from more than one project directory.
A scanner that treats every file as a separate conversation will duplicate rows and reminders. Agent Island groups candidates by provider and session identity, then keeps the newest valid record. Internal exec runs, probes, bridge sessions, and automation records are filtered because they do not represent a human conversation waiting for attention.
Subagent threads need their own rule. A fan-out can finish many child tasks while the main turn remains active. Hiding those child alarms by default prevents a burst of machine completions from looking like several user handoffs.
Each visible thread gets one local state:
fresh assistant output, no stop marker working
fresh main-turn completion your turn
recently working, then quiet stalled
old semantic activity idle
The provider still has only one position in the menu bar, so the states need a priority order. The current model uses:
unacknowledged your turn
stalled
working
acknowledged your turn
idle
An unanswered turn wins because the user can act on it. After that turn is acknowledged, a different session that is actively working should become visible. Without this distinction, a static completion badge can hide fresh activity elsewhere.
Within the same state, semantic event time wins over file modification time. Metadata and bookkeeping can touch a transcript after the event that changed the conversation.
The provider status is a summary. The reminder key still includes the provider, session identity, and turn identity.
That key stops the same completed turn from alerting on every scan. A later turn in the same conversation gets a new key. If another distinct handoff arrives while a panel is visible, it can wait in a queue instead of replacing the first one.
The inverse matters too. A reply changes the evidence. When the transcript leaves the needs-you state, any pending reminder for that turn is cancelled and a visible panel can close. A reminder that cannot retract itself eventually becomes stale UI.
Polling alone creates visible delay. Filesystem events alone can be missed after sleep, a watch restart, or a burst of writes.
Agent Island uses transcript events for the fast path and a six-second timer for recovery. Event-driven scans are throttled and receive a trailing pass, so a final completion marker is not hidden behind the preceding stream of token writes. Parsing happens away from the UI thread, then the chosen provider states are published together.
This model still has limits. Local events cannot prove that a task is making useful progress, estimate remaining time, or diagnose a tool call blocked on an external service. The monitor reports observable state and takes the user back to the relevant thread. It does not restart work or claim to understand the task.
Agent Island 1.7.1 applies this approach to Claude Code and Codex on macOS and Windows. It is free, open source, and keeps session data on the local machine.