<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: tristan666666</title>
    <description>The latest articles on DEV Community by tristan666666 (@tristan666666).</description>
    <link>https://dev.to/tristan666666</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3991319%2F440d9f0e-48fd-448c-b75c-f755a6fdc7f8.png</url>
      <title>DEV Community: tristan666666</title>
      <link>https://dev.to/tristan666666</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tristan666666"/>
    <language>en</language>
    <item>
      <title>How Agent Island Detects Claude Code and Codex Session State</title>
      <dc:creator>tristan666666</dc:creator>
      <pubDate>Thu, 18 Jun 2026 17:19:00 +0000</pubDate>
      <link>https://dev.to/tristan666666/how-agent-island-detects-claude-code-and-codex-session-state-2p93</link>
      <guid>https://dev.to/tristan666666/how-agent-island-detects-claude-code-and-codex-session-state-2p93</guid>
      <description>&lt;p&gt;I built Agent Island around a small problem that becomes painful during long agentic coding runs: the task does not always fail loudly.&lt;/p&gt;

&lt;p&gt;A Claude Code or Codex session may still be working, may have finished and be waiting for your next instruction, or may have frozen mid-turn. If that happens while you are away from the keyboard, the only visible signal is usually buried in a terminal or transcript file.&lt;/p&gt;

&lt;p&gt;Agent Island turns that into a local macOS signal in the MacBook notch / menu-bar area:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;working&lt;/strong&gt;: the provider logo breathes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;your turn&lt;/strong&gt;: the provider logo spins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stalled&lt;/strong&gt;: the provider logo turns red and can play a short beep sequence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Launch video: &lt;a href="https://github.com/user-attachments/assets/d69b41e0-9298-4f17-b6c9-6014f3bd956b" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/d69b41e0-9298-4f17-b6c9-6014f3bd956b&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/tristan666666/agent-island" rel="noopener noreferrer"&gt;https://github.com/tristan666666/agent-island&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download DMG (macOS 13+): &lt;a href="https://github.com/tristan666666/agent-island/releases/download/v1.0.0/AgentIsland-1.0.0.dmg" rel="noopener noreferrer"&gt;https://github.com/tristan666666/agent-island/releases/download/v1.0.0/AgentIsland-1.0.0.dmg&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The data source is local
&lt;/h2&gt;

&lt;p&gt;There is no shared live-state API for Claude Code and Codex CLI sessions, so Agent Island reads the same local artifacts the tools already write.&lt;/p&gt;

&lt;p&gt;Claude Code activity is detected from JSONL transcript files under:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.claude/projects/*.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trigger picker uses Claude Desktop's session store for nicer labels and archived filtering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/Library/Application Support/Claude/claude-code-sessions/local_*.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Codex activity is detected from recent JSONL sessions under:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.codex/sessions/YYYY/MM/DD/*.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Codex session labels, Agent Island reads the first &lt;code&gt;session_meta&lt;/code&gt; JSONL event and uses its &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;cwd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This keeps state detection local. The app does not need a third-party service just to decide whether a session is still moving.&lt;/p&gt;

&lt;h2&gt;
  
  
  The state model
&lt;/h2&gt;

&lt;p&gt;The scanner runs every six seconds and classifies each candidate transcript. File I/O happens off the main actor so the notch UI stays responsive.&lt;/p&gt;

&lt;p&gt;The core inputs are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transcript modification time&lt;/li&gt;
&lt;li&gt;the last few JSONL events&lt;/li&gt;
&lt;li&gt;whether this app has recently observed the file producing output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current thresholds are intentionally conservative:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Threshold&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;active window&lt;/td&gt;
&lt;td&gt;18 seconds&lt;/td&gt;
&lt;td&gt;Fresh transcript writes mean the session is working.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stall after&lt;/td&gt;
&lt;td&gt;300 seconds&lt;/td&gt;
&lt;td&gt;A watched working session that freezes mid-turn for 5 minutes becomes stalled.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;stall cap&lt;/td&gt;
&lt;td&gt;15 minutes&lt;/td&gt;
&lt;td&gt;Past this, the app treats it as idle rather than a live stall.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;needs-you cap&lt;/td&gt;
&lt;td&gt;20 minutes&lt;/td&gt;
&lt;td&gt;A finished turn is only surfaced as "your turn" while it is still fresh.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;attention window&lt;/td&gt;
&lt;td&gt;30 minutes&lt;/td&gt;
&lt;td&gt;Old transcripts are ignored.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last point matters. Agent Island only sounds the alarm if it first saw the session working. A transcript that was already old when the app launched should not suddenly become a red alert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detecting "your turn"
&lt;/h2&gt;

&lt;p&gt;Agent Island tails the last 128 KB of the transcript, capped to 200 lines, so a recent completion marker is unlikely to be pushed out by a burst of tool output.&lt;/p&gt;

&lt;p&gt;For Claude Code, the scanner looks for an assistant event whose stop reason indicates the assistant turn is complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stop_reason: end_turn
stop_reason: stop_sequence
stop_reason: stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Codex, the scanner looks for Codex event messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;payload.type: task_complete
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a newer &lt;code&gt;task_started&lt;/code&gt; appears before a completion marker, Codex is treated as still working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detecting stalled sessions
&lt;/h2&gt;

&lt;p&gt;A stalled session is not just "a file did not change for a while." That would be too noisy.&lt;/p&gt;

&lt;p&gt;The scanner only returns stalled when all of these are true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the transcript was recently observed in the working state&lt;/li&gt;
&lt;li&gt;the transcript has stopped changing for at least five minutes&lt;/li&gt;
&lt;li&gt;no fresh turn-complete marker is visible in the tail&lt;/li&gt;
&lt;li&gt;the session is still inside the 15-minute stall cap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This catches the failure mode the app cares about: a long-running agent that was active, then froze mid-turn while you were not watching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aggregating per provider
&lt;/h2&gt;

&lt;p&gt;Claude and Codex can each have multiple candidate transcripts. Agent Island classifies each file, then takes the most urgent state for that provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idle &amp;lt; working &amp;lt; your turn &amp;lt; stalled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives one visible Claude state and one visible Codex state in the notch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auto-resume is separate from state detection
&lt;/h2&gt;

&lt;p&gt;The visual state monitor is passive. Auto-resume is explicit and opt-in.&lt;/p&gt;

&lt;p&gt;A trigger contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provider: Claude or Codex&lt;/li&gt;
&lt;li&gt;session id&lt;/li&gt;
&lt;li&gt;working directory&lt;/li&gt;
&lt;li&gt;message to send&lt;/li&gt;
&lt;li&gt;trigger mode&lt;/li&gt;
&lt;li&gt;enabled state&lt;/li&gt;
&lt;li&gt;last fired time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two trigger modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;after reset&lt;/strong&gt;: fire once after the provider's real reset boundary advances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;every N hours&lt;/strong&gt;: fire on a fixed local interval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reset-based mode is deliberately not "wait five hours from now." The app watches the provider usage store and treats a changed reset boundary as the reset signal. That prevents relaunches from firing immediately and lets the app catch up once if the Mac slept through a genuine rollover.&lt;/p&gt;

&lt;h2&gt;
  
  
  The risk boundary
&lt;/h2&gt;

&lt;p&gt;When a trigger fires, Agent Island resumes the selected CLI session using the provider's resume command. Those flags are powerful: they bypass normal approval prompts and can spend tokens.&lt;/p&gt;

&lt;p&gt;That is why auto-resume is not the default experience. The app makes it explicit in the README and UI: only attach triggers to sessions you trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this belongs in the notch
&lt;/h2&gt;

&lt;p&gt;This is not trying to replace a terminal UI, dashboard, or session browser. Those are useful when you want detail.&lt;/p&gt;

&lt;p&gt;The notch is for a narrower job: a persistent, low-friction signal that answers one question while you work on something else:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is my agent still moving, waiting for me, or stuck?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the surface Agent Island optimizes for.&lt;/p&gt;

&lt;p&gt;Feedback is welcome, especially from people who run Claude Code or Codex for long refactors and maintenance tasks.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>swift</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
