<?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: Agent Island</title>
    <description>The latest articles on DEV Community by Agent Island (@agentis).</description>
    <link>https://dev.to/agentis</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%2F4027807%2F6cf08827-f073-40e0-88e0-f303ffba3e3c.png</url>
      <title>DEV Community: Agent Island</title>
      <link>https://dev.to/agentis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agentis"/>
    <language>en</language>
    <item>
      <title>Stop Background Agents From Triggering Foreground Alerts</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Wed, 15 Jul 2026 17:32:01 +0000</pubDate>
      <link>https://dev.to/agentis/stop-background-agents-from-triggering-foreground-alerts-1176</link>
      <guid>https://dev.to/agentis/stop-background-agents-from-triggering-foreground-alerts-1176</guid>
      <description>&lt;p&gt;A background review worker finishes while the main coding-agent session is still running. If the monitor scans for the latest completion marker, it tells the user to return too early.&lt;/p&gt;

&lt;p&gt;The fix starts with source classification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude sidechains
&lt;/h2&gt;

&lt;p&gt;Claude records may place workers in &lt;code&gt;subagents&lt;/code&gt; files or interleave lines marked &lt;code&gt;isSidechain&lt;/code&gt; into the main transcript. The main parser skips sidechain lines. Separate agent transcripts enter normal monitoring only when subagent alerts are enabled.&lt;/p&gt;

&lt;p&gt;Tests cover both dangerous orders: a sidechain &lt;code&gt;end_turn&lt;/code&gt; after the main assistant starts a tool, and trailing sidechain traffic after the main assistant really finishes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codex rollout sources
&lt;/h2&gt;

&lt;p&gt;Codex session metadata distinguishes interactive CLI work from &lt;code&gt;exec&lt;/code&gt;, internal activity, and structured subagents. A foreign originator is treated as automation even if another field resembles a worker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interactive -&amp;gt; normal status
subagent     -&amp;gt; opt-in alerts
automation   -&amp;gt; no user-turn alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Classification happens before sessions are reduced to one provider-level state. Otherwise the monitor loses the identity needed to remove a worker's false completion.&lt;/p&gt;

&lt;p&gt;I help run Agent Island, where this filter protects local Claude Code and Codex alerts. This draft stays on publication hold pending canonical verification.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>observability</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why a Coding-Agent Completion Event Is Not Enough</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Wed, 15 Jul 2026 17:31:34 +0000</pubDate>
      <link>https://dev.to/agentis/why-a-coding-agent-completion-event-is-not-enough-lci</link>
      <guid>https://dev.to/agentis/why-a-coding-agent-completion-event-is-not-enough-lci</guid>
      <description>&lt;p&gt;A terminal monitor sees &lt;code&gt;task_complete&lt;/code&gt;. It sends an alert. The user returns and finds that the event belongs to an old turn, a background worker, or a session they already resumed.&lt;/p&gt;

&lt;p&gt;The parser found a real event. The product state was still wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Return more than a boolean
&lt;/h2&gt;

&lt;p&gt;Our local parser returns a completion flag, a turn key, and the event's semantic timestamp. The turn key deduplicates repeated observations. The timestamp lets later activity revoke the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TurnStatus {
  isDone
  turnKey
  activityDate
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude and Codex need separate adapters. Claude stop reasons are not sufficient on their own because an API-error record can use a completion-shaped envelope. Codex uses event types such as &lt;code&gt;task_complete&lt;/code&gt; and &lt;code&gt;turn/completed&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat completion as a lease
&lt;/h2&gt;

&lt;p&gt;The monitor combines the turn timestamp with newer local session activity. A fresh completed turn becomes &lt;code&gt;needsYou&lt;/code&gt;. Newer user activity can move it back to working, while the freshness cap eventually returns it to idle.&lt;/p&gt;

&lt;p&gt;Filesystem modification time remains a fallback. It cannot be the main clock because bookkeeping writes do not carry the same meaning as user activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tradeoffs
&lt;/h2&gt;

&lt;p&gt;A longer attention window preserves alerts for users who step away, but keeps old state around longer. Watchers improve latency, but a periodic scan is still needed for dropped events. Upstream record changes require parser fixtures that cover errors and later activity, not just the happy path.&lt;/p&gt;

&lt;p&gt;I help run Agent Island, where this state model is used for local Claude Code and Codex monitoring. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>observability</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Finish Notification Is a Lease, Not a Boolean</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Wed, 15 Jul 2026 08:15:33 +0000</pubDate>
      <link>https://dev.to/agentis/a-finish-notification-is-a-lease-not-a-boolean-n8k</link>
      <guid>https://dev.to/agentis/a-finish-notification-is-a-lease-not-a-boolean-n8k</guid>
      <description>&lt;p&gt;A coding agent finishes a turn. The monitor schedules an alert. Two seconds later, the developer has already replied.&lt;/p&gt;

&lt;p&gt;Should the notification still appear?&lt;/p&gt;

&lt;p&gt;If completion is stored as a boolean, the answer is usually yes. The alert was scheduled from a true value, and the delayed task has no reason to question it. The result is a technically accurate notification that is already obsolete.&lt;/p&gt;

&lt;p&gt;We found it more useful to model a completion as a short-lived lease on human attention. The lease has an identity, a freshness boundary, and a condition that can disappear before or after delivery.&lt;/p&gt;

&lt;h2&gt;
  
  
  Detection is not permission to interrupt
&lt;/h2&gt;

&lt;p&gt;The local session scanner and the reminder system answer different questions.&lt;/p&gt;

&lt;p&gt;The scanner asks whether the latest meaningful evidence says the agent ended a turn. The reminder system asks whether this is a new handoff that still needs the user.&lt;/p&gt;

&lt;p&gt;That separation matters at startup. A completed transcript may be correct status information, but it is not necessarily new information. Replaying every completion found on disk when the app opens would turn accurate history into noisy alerts.&lt;/p&gt;

&lt;p&gt;Agent Island therefore baselines completed turns it discovers at startup. They can appear in the status surface without being treated as newly created interruptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-check state at delivery time
&lt;/h2&gt;

&lt;p&gt;Local session files change quickly around a handoff. A user can return to the terminal before a notification delay expires. A client can also append bookkeeping data after the assistant's terminal event.&lt;/p&gt;

&lt;p&gt;The reminder is scheduled with a short delay, then validates the current state again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alerts enabled
+ same turn still needs attention
+ turn has not been acknowledged
+ turn has not already been delivered
= show the alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second check is the important part. A delayed task should not trust the snapshot that created it.&lt;/p&gt;

&lt;p&gt;This pattern applies beyond coding agents. Any notification based on a reversible condition should verify that condition immediately before interrupting the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give the handoff a stable identity
&lt;/h2&gt;

&lt;p&gt;Deduplicating on provider name is too broad. One Claude session can finish several turns. Deduplicating on the latest file timestamp is too narrow because the same turn can be observed through repeated scans.&lt;/p&gt;

&lt;p&gt;The delivery key needs enough context to identify the handoff: provider, session, project, transcript, and turn identity. Repeated observations of that key are one event. A later turn gets a different key even when it belongs to the same session.&lt;/p&gt;

&lt;p&gt;Delivered and acknowledged keys are retained for a bounded period. That prevents a refresh from replaying an old alert without turning the reminder layer into a permanent transcript database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cancellation has to work after delivery too
&lt;/h2&gt;

&lt;p&gt;Preventing an alert before it appears solves only half of the stale-state problem.&lt;/p&gt;

&lt;p&gt;The user may reply from another window while the notification panel is already visible. On each scan, the reminder layer compares the current attention keys with the previous set. When a key disappears, it cancels the pending task and dismisses the corresponding visible alert.&lt;/p&gt;

&lt;p&gt;The UI follows the source condition instead of asking the user to close evidence that is no longer true.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bursts are one human event more often than many
&lt;/h2&gt;

&lt;p&gt;Agent workflows can finish several child sessions within seconds. The filesystem sees multiple completions. The person supervising the run may see one parent workflow reaching a handoff.&lt;/p&gt;

&lt;p&gt;Delivering every child completion optimizes for event count, not attention. The reminder layer selects the newest relevant turn and baselines the rest of the burst. Subagent alerts remain opt-in because child-session traffic can otherwise dominate the signal from the main session.&lt;/p&gt;

&lt;h2&gt;
  
  
  The return action must be honest
&lt;/h2&gt;

&lt;p&gt;A useful alert identifies the provider, project, and session. Its action should return the developer to that work.&lt;/p&gt;

&lt;p&gt;For a Claude CLI session, a known session ID can be resumed in a terminal. Claude Desktop does not expose the same exact-conversation routing contract. In that case, activating the app and copying the session title for search is more honest than labeling an imprecise action as a guaranteed deep link.&lt;/p&gt;

&lt;p&gt;Platform limits belong in the interaction design, not in a footnote after the button fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the signal does not prove
&lt;/h2&gt;

&lt;p&gt;"Your turn" means the local evidence says an agent ended a turn and a response is still needed. It does not mean the generated code is correct, the task is complete, or the output is safe to merge.&lt;/p&gt;

&lt;p&gt;That boundary keeps the alert useful. The monitor owns attention state; the developer still owns verification.&lt;/p&gt;

&lt;p&gt;The full setup and behavior guide is here: &lt;a href="https://agent-island.dev/guides/get-notified-when-claude-code-finishes/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=claude_alert_july15" rel="noopener noreferrer"&gt;Get notified when Claude Code finishes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Agent Island is open source for macOS and Windows: &lt;a href="https://github.com/tristan666666/agent-island?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=claude_alert_july15" rel="noopener noreferrer"&gt;source and releases&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>claude</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Last JSONL Line Is Not a State Machine</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Wed, 15 Jul 2026 07:24:09 +0000</pubDate>
      <link>https://dev.to/agentis/the-last-jsonl-line-is-not-a-state-machine-pnd</link>
      <guid>https://dev.to/agentis/the-last-jsonl-line-is-not-a-state-machine-pnd</guid>
      <description>&lt;p&gt;A transcript ended with an assistant message. Is Claude Code finished?&lt;/p&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;That line may be the end of the current turn. It may belong to an old session. Claude Desktop may have written bookkeeping metadata after it. The user may already have replied. Or the assistant message may actually be an API error carrying a stop reason that looks deceptively final.&lt;/p&gt;

&lt;p&gt;This is the awkward part of building a local status monitor: parsing JSONL is easy. Deciding what the evidence means right now is the engineering work.&lt;/p&gt;

&lt;h2&gt;
  
  
  File activity is evidence, not state
&lt;/h2&gt;

&lt;p&gt;Claude Code and Claude Desktop already leave useful records on the machine. A local companion can inspect them without shipping transcripts to a hosted service. That gives us a strong privacy boundary, but it also removes the convenience of asking a server for a single authoritative status.&lt;/p&gt;

&lt;p&gt;The first implementation temptation is to map modification time directly to state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;modified recently -&amp;gt; working
not modified -&amp;gt; idle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It fails in both directions. A session may be working while writes arrive in bursts. A metadata write may touch a file after the actual turn ended. A quiet file may mean the model is thinking, waiting on a tool, stalled, or simply abandoned.&lt;/p&gt;

&lt;p&gt;The timestamp is useful, but it cannot carry the whole decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Completion has to survive newer noise
&lt;/h2&gt;

&lt;p&gt;For Claude, a terminal assistant event is one input to the your-turn decision. The scanner also tracks the event identity and semantic timestamp. That matters because Claude Desktop can update its activity record a few seconds after the final assistant event.&lt;/p&gt;

&lt;p&gt;If every newer desktop timestamp meant "the user came back," that bookkeeping write would erase the completion state before the alert fired. We give that short post-completion write a grace window. Activity well after the grace is different: it is evidence that the user probably returned, so the old completion should be suppressed.&lt;/p&gt;

&lt;p&gt;This distinction came directly from observed event ordering. It is not something a generic file watcher can infer.&lt;/p&gt;

&lt;h2&gt;
  
  
  A new turn cancels the old answer
&lt;/h2&gt;

&lt;p&gt;The parser works from the latest meaningful main-thread event, not merely the last physical line. A user event after an assistant completion means the old handoff is over. A streaming assistant event without a terminal stop remains working.&lt;/p&gt;

&lt;p&gt;Sidechain events need separate treatment. Tool and subagent traffic can appear after the main assistant event. Letting a sidechain completion finish the main turn creates noisy alerts; letting trailing sidechain lines hide a real main-thread completion loses alerts. The parser therefore identifies the latest relevant main-thread event first.&lt;/p&gt;

&lt;p&gt;API errors are another trap. A rate-limit response may be represented as an assistant line with a stop reason. That is attention, but it is not a successful your-turn completion. The error marker must win.&lt;/p&gt;

&lt;h2&gt;
  
  
  State needs an expiry policy
&lt;/h2&gt;

&lt;p&gt;Even a correctly detected completion is not fresh forever.&lt;/p&gt;

&lt;p&gt;Our scanner keeps bounded windows for working, your turn, stalled, and attention. A session previously observed as working can become stalled after sustained silence. A completed turn eventually ages back to idle. Evidence outside the attention window is ignored.&lt;/p&gt;

&lt;p&gt;The exact thresholds are implementation details that may change. The invariant is more important:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;old evidence must not create a new interruption
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That rule also applies at app launch. Existing completed turns become baseline history. We do not pop an alarm for every session that finished before the monitor started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple files still have to become one signal
&lt;/h2&gt;

&lt;p&gt;A real machine can have duplicate Claude Desktop records, archived threads, main transcripts, and subagent transcripts. A status bar cannot render that raw inventory.&lt;/p&gt;

&lt;p&gt;The monitor filters archived and machine-driven sessions, deduplicates repeated session IDs, and then chooses the most urgent current state for the provider. Subagent alarms remain opt-in because orchestration can finish many child turns in a burst while the human only cares about the parent workflow.&lt;/p&gt;

&lt;p&gt;This is less impressive than claiming "real-time AI observability," but it is more useful. The user needs one defensible answer: working, your turn, or attention required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests should encode event order, not just fixtures
&lt;/h2&gt;

&lt;p&gt;The regression cases that matter are sequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assistant completion, then a user reply;&lt;/li&gt;
&lt;li&gt;completion, then a short bookkeeping write;&lt;/li&gt;
&lt;li&gt;completion, then genuine later desktop activity;&lt;/li&gt;
&lt;li&gt;sidechain completion after unfinished main output;&lt;/li&gt;
&lt;li&gt;API-error assistant line with a stop reason;&lt;/li&gt;
&lt;li&gt;old semantic activity with a freshly touched file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each sequence protects a state transition. A parser test that only checks whether one JSON object can be decoded would miss the actual failures.&lt;/p&gt;

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

&lt;p&gt;A local monitor can tell us that Claude is producing output, ended a turn, or appears to need attention. It cannot prove the requested task is correct or that generated code is safe. "Your turn" means a reply is needed, not that the engineering work is done.&lt;/p&gt;

&lt;p&gt;Agent Island uses this local model for its Claude Code and Codex status surface. The longer engineering guide, including the freshness boundaries and released scope, is here: &lt;a href="https://agent-island.dev/claude-code-status-monitor/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=claude_status_july15" rel="noopener noreferrer"&gt;Claude Code status monitor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project is open source: &lt;a href="https://github.com/tristan666666/agent-island?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=claude_status_july15" rel="noopener noreferrer"&gt;inspect the scanner and tests on GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why a Local Token Estimate Is Not Your Claude or Codex Bill</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:15:13 +0000</pubDate>
      <link>https://dev.to/agentis/why-a-local-token-estimate-is-not-your-claude-or-codex-bill-2fan</link>
      <guid>https://dev.to/agentis/why-a-local-token-estimate-is-not-your-claude-or-codex-bill-2fan</guid>
      <description>&lt;p&gt;A token log can support a dollar estimate. It cannot tell you what a subscription cost.&lt;/p&gt;

&lt;p&gt;The distinction sounds obvious until a report card shows a large number. Without a visible definition, readers interpret it as spend or savings. The implementation needs an accounting rule before it needs a chart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculate by token category
&lt;/h2&gt;

&lt;p&gt;For each local usage event, keep input, output, cache creation, and cache reads separate. Apply the matching per-million rate to each category and add the results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;value = input * input_rate
      + output * output_rate
      + cache_create * cache_create_rate
      + cache_read * cache_read_rate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each token quantity is divided by one million in the actual calculation. The rate table must carry a snapshot date.&lt;/p&gt;

&lt;p&gt;Codex needs an extra parsing step because its input count includes cached input. Subtract the cached portion first, then price normal input and cache reads separately. Otherwise the cached tokens are charged twice in the estimate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not guess unknown models
&lt;/h2&gt;

&lt;p&gt;A newly released model can appear before the embedded table knows its rate. Assigning a nearby model's price makes the total look complete but weakens its meaning.&lt;/p&gt;

&lt;p&gt;The macOS v1.6.1 implementation I work on prices a named model missing from the rate table at zero and records an unpriced warning. A Codex row received before model context instead uses the parser's &lt;code&gt;gpt-5.4&lt;/code&gt; model fallback. The displayed total can be low, but the gap is visible and correctable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the claim
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;API value&lt;/code&gt; means the value of recorded token activity under a dated API-price snapshot.&lt;/p&gt;

&lt;p&gt;It does not mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;subscription spend;&lt;/li&gt;
&lt;li&gt;money saved;&lt;/li&gt;
&lt;li&gt;revenue;&lt;/li&gt;
&lt;li&gt;an exact provider invoice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Actual spend requires billing records, credits, taxes, discounts, and contract terms. Local session logs do not contain that information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep volume separate
&lt;/h2&gt;

&lt;p&gt;Wire-token volume includes cache activity. API value applies different prices to each category. A cache-heavy week can have a large token count and a much smaller value estimate than its headline suggests.&lt;/p&gt;

&lt;p&gt;Showing both measures is useful. Naming them precisely prevents one from borrowing the meaning of the other.&lt;/p&gt;

&lt;p&gt;I build Agent Island, and this article describes the released macOS calculation. The broader rule applies to any local usage tool: date the prices, preserve cache semantics, expose unknown models, and never label a counterfactual as a bill.&lt;/p&gt;

&lt;p&gt;The full definition and implementation boundaries are documented on the &lt;a href="https://agent-island.dev/blog/api-value-vs-ai-coding-bill/?utm_source=dev.to&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=api-value"&gt;Agent Island Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Parsing Claude Code and Codex Logs Without Double-Counting a Week</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:10:54 +0000</pubDate>
      <link>https://dev.to/agentis/parsing-claude-code-and-codex-logs-without-double-counting-a-week-9m9</link>
      <guid>https://dev.to/agentis/parsing-claude-code-and-codex-logs-without-double-counting-a-week-9m9</guid>
      <description>&lt;p&gt;Adding every token number found in a JSONL file produces a convincing but unreliable report.&lt;/p&gt;

&lt;p&gt;Claude Code and Codex record usage differently. Claude assistant messages expose separate input, output, cache-creation, and cache-read fields. Codex rollout files split the active model and the per-turn usage across different row types. A local ledger needs to preserve those differences before it can combine anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Normalize at one boundary
&lt;/h2&gt;

&lt;p&gt;The Claude reader accepts assistant messages with a usage object. It deduplicates a row only when both message ID and request ID exist, skips synthetic model placeholders, and keeps the four token categories separate.&lt;/p&gt;

&lt;p&gt;The Codex reader carries the model from &lt;code&gt;turn_context&lt;/code&gt; into later &lt;code&gt;token_count&lt;/code&gt; events. It uses &lt;code&gt;last_token_usage&lt;/code&gt;, not the cumulative total, because cumulative values can repeat earlier work in forked sessions. Cached input is included inside Codex input, so it is subtracted before the remaining input is priced.&lt;/p&gt;

&lt;p&gt;Both readers then emit the same event shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider, timestamp, model,
input, output, cache_creation, cache_read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything after that point operates on normalized events rather than provider-specific JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use calendar buckets for a calendar report
&lt;/h2&gt;

&lt;p&gt;The weekly card covers today and the previous six local calendar days. The per-model slice uses that same boundary.&lt;/p&gt;

&lt;p&gt;A rolling 168-hour model slice looks reasonable, but it can include part of an eighth calendar day. The model rows then exceed the daily-bar total. Sharing one midnight-aligned boundary removes that mismatch.&lt;/p&gt;

&lt;p&gt;The aggregate keeps two token measures. Wire tokens include cache activity; the narrower measure includes input and output. Estimated API value is calculated separately with dated per-token rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the share path local
&lt;/h2&gt;

&lt;p&gt;The report image is rendered on the machine. The app writes it to the clipboard or opens the system share picker only after the user clicks a button. It does not upload the report or transcript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;local logs -&amp;gt; token events -&amp;gt; daily aggregates -&amp;gt; local image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That short path is easier to explain and inspect than an analytics-backed report service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tradeoffs
&lt;/h2&gt;

&lt;p&gt;Deleted logs cannot be recovered. Local formats can change. A named model missing from the embedded price table is priced at zero and should produce an unpriced warning. An early Codex row with no model context is a separate case: the parser applies its &lt;code&gt;gpt-5.4&lt;/code&gt; model fallback. A token count also says nothing about code quality.&lt;/p&gt;

&lt;p&gt;I build Agent Island, the open-source app whose macOS v1.6.1 implementation this article describes. The useful lesson is independent of the app: normalize provider records once, preserve cache semantics, and align every report component to the same time boundary.&lt;/p&gt;

&lt;p&gt;The full engineering article and source context are available on the &lt;a href="https://agent-island.dev/blog/claude-code-codex-weekly-work-ledger/?utm_source=dev.to&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=weekly-ledger"&gt;Agent Island Blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>swift</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Hello DEV: Building Agent Island for Claude Code and Codex</title>
      <dc:creator>Agent Island</dc:creator>
      <pubDate>Tue, 14 Jul 2026 12:47:59 +0000</pubDate>
      <link>https://dev.to/agentis/hello-dev-building-agent-island-for-claude-code-and-codex-4d6d</link>
      <guid>https://dev.to/agentis/hello-dev-building-agent-island-for-claude-code-and-codex-4d6d</guid>
      <description>&lt;p&gt;Hi DEV — I'm the maker of &lt;strong&gt;Agent Island&lt;/strong&gt;, a free and open-source status companion for Claude Code and Codex.&lt;/p&gt;

&lt;p&gt;I built it around a simple problem: coding agents often finish, need input, or hit an error in another window while you're focused elsewhere. The work may be done, but the handoff is easy to miss.&lt;/p&gt;

&lt;p&gt;Agent Island makes those session states visible in one place. It shows which agent and project need attention, sends a notification, and can play a sound when it is your turn. The product is local-first, and session state stays on the machine.&lt;/p&gt;

&lt;p&gt;I'm here to share practical notes from building and shipping a cross-platform developer tool, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;designing reliable state detection for long-running agent sessions&lt;/li&gt;
&lt;li&gt;building useful notifications without creating noise&lt;/li&gt;
&lt;li&gt;keeping the product local-first&lt;/li&gt;
&lt;li&gt;shipping for macOS and Windows&lt;/li&gt;
&lt;li&gt;learning what developers actually need from agent observability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is available at &lt;a href="https://agent-island.dev/" rel="noopener noreferrer"&gt;agent-island.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm especially interested in how other developers manage several agent sessions at once. What part of that workflow creates the most friction for you?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
