<?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: Arthur</title>
    <description>The latest articles on DEV Community by Arthur (@atoll92).</description>
    <link>https://dev.to/atoll92</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%2F4188891%2Fdd2c0651-a7f2-4d52-bfcd-a2d227eb6ec9.jpg</url>
      <title>DEV Community: Arthur</title>
      <link>https://dev.to/atoll92</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atoll92"/>
    <language>en</language>
    <item>
      <title>I stopped babysitting my AI agents. Now they hold a standup.</title>
      <dc:creator>Arthur</dc:creator>
      <pubDate>Tue, 27 Oct 2026 01:12:31 +0000</pubDate>
      <link>https://dev.to/atoll92/i-stopped-babysitting-my-ai-agents-now-they-hold-a-standup-74m</link>
      <guid>https://dev.to/atoll92/i-stopped-babysitting-my-ai-agents-now-they-hold-a-standup-74m</guid>
      <description>&lt;p&gt;Running coding agents in parallel has a hidden job attached: checking on them.&lt;/p&gt;

&lt;p&gt;You start three Claude Code sessions, one of them spawns four sub-agents, a Codex thread is running a migration somewhere. Then you spend the afternoon alt-tabbing between terminals asking the same three questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this one still working, or is it stuck on a command?&lt;/li&gt;
&lt;li&gt;Is that one waiting for &lt;em&gt;me&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;Which sub-agent just burned 400k tokens?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I got tired of being the person refreshing terminals, so I built the thing I wanted to look at instead: a stand-up call.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1jxwrgdlnfh2knez5tye.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1jxwrgdlnfh2knez5tye.gif" alt="The demo call: a lead agent and its sub-agents at their desks" width="719" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually is
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Atoll92/agent-standup" rel="noopener noreferrer"&gt;Agent Standup&lt;/a&gt; reads the session files that Claude Code, Codex and Mistral Vibe already write to disk, and plays them as a live team call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;lead&lt;/strong&gt; agent gives the orders. &lt;strong&gt;Sub-agents join the call&lt;/strong&gt; when they get a task, work at their desks, report back, and leave.&lt;/li&gt;
&lt;li&gt;Whoever is working &lt;strong&gt;shares their screen&lt;/strong&gt;: the real command and its real output, or the exact diff it's applying.&lt;/li&gt;
&lt;li&gt;Each tile has &lt;strong&gt;one status&lt;/strong&gt;: working, waiting on another agent, needs you, done. A tile pulses amber when a command has run for over a minute, and shows 💤 when an agent has gone quiet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokens per agent&lt;/strong&gt;, so the expensive sub-agent is obvious.&lt;/li&gt;
&lt;li&gt;It only calls you in when an agent &lt;strong&gt;actually needs you&lt;/strong&gt; (a permission prompt, a question), not every time a turn ends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It costs zero tokens: it never calls a model to watch your agents, it just reads files. It runs locally and sends nothing by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fojp1cx3ukgx4ptzst301.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fojp1cx3ukgx4ptzst301.jpg" alt="The shared screen: a sub-agent's terminal with real output" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Yes, they talk
&lt;/h2&gt;

&lt;p&gt;The agents speak their updates out loud, with a small speech model that runs on your machine, and their mouths move with the voice. You can switch to an Animal Crossing–style babble, or mute it.&lt;/p&gt;

&lt;p&gt;This is the part people call a gimmick, and on Hacker News some did. Fair. But here's what I found: I &lt;em&gt;notice&lt;/em&gt; a voice saying "I need you to approve this" from across the room. I don't notice a terminal that silently stopped scrolling. Sound turned out to be the feature, not the decoration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things I learned reading agent logs
&lt;/h2&gt;

&lt;p&gt;None of these formats is documented, so the reader has to be defensive. A few traps, in case you're building something similar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Token usage is repeated.&lt;/strong&gt; Claude Code writes the same assistant message once per content block, each copy with identical &lt;code&gt;usage&lt;/code&gt;. Count once per &lt;code&gt;message.id&lt;/code&gt;, or a five-block message costs five times as much.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Quiet" doesn't mean "done".&lt;/strong&gt; The end of a turn is an explicit &lt;code&gt;stop_reason: "end_turn"&lt;/code&gt; mark. Until it arrives the agent is still working, even after a minute of silence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most Codex sub-threads aren't yours.&lt;/strong&gt; On my machine, 34 of 57 Codex rollouts were short automatic "guardian" reviews. Show them all and the list drowns.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wrote the full field guide (where each tool keeps its sessions, how sub-agents show up, how to survive format changes) in &lt;a href="https://dev.to/atoll92/-reading-the-undocumented-session-logs-of-claude-code-codex-and-mistral-vibe-4i67"&gt;Reading the undocumented session logs of Claude Code, Codex and Mistral Vibe&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;No install, from any terminal (Node 18+):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @double_geste/agent-standup@latest &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No sessions yet? ⚙ → Source → &lt;strong&gt;Demo&lt;/strong&gt; plays a fictional team fixing a slow login page.&lt;/p&gt;

&lt;p&gt;It's also a &lt;a href="https://marketplace.visualstudio.com/items?itemName=DoubleGeste.agent-standup" rel="noopener noreferrer"&gt;VS Code extension&lt;/a&gt; (Cursor and Windsurf via &lt;a href="https://open-vsx.org/extension/DoubleGeste/agent-standup" rel="noopener noreferrer"&gt;Open VSX&lt;/a&gt;), a Claude Code plugin, and a macOS app. MIT licensed, interface in 10 languages: &lt;a href="https://github.com/Atoll92/agent-standup" rel="noopener noreferrer"&gt;github.com/Atoll92/agent-standup&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your turn
&lt;/h2&gt;

&lt;p&gt;I'm curious how other people handle this, because I don't think a cartoon call is the only answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many agent sessions do you run at once, and how do you know which one needs you?&lt;/strong&gt; Separate terminal tabs? tmux? Notifications? Just... checking a lot?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>showdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Reading the undocumented session logs of Claude Code, Codex and Mistral Vibe</title>
      <dc:creator>Arthur</dc:creator>
      <pubDate>Fri, 16 Oct 2026 12:50:35 +0000</pubDate>
      <link>https://dev.to/atoll92/-reading-the-undocumented-session-logs-of-claude-code-codex-and-mistral-vibe-4i67</link>
      <guid>https://dev.to/atoll92/-reading-the-undocumented-session-logs-of-claude-code-codex-and-mistral-vibe-4i67</guid>
      <description>&lt;h2&gt;
  
  
  Why read the logs at all
&lt;/h2&gt;

&lt;p&gt;Claude Code, Codex and Mistral Vibe all write everything they do to disk, as they do it, and none of them documents the format. If you run a few sessions that spawn sub-agents, those files are the only place that knows which agent is still working, which one is waiting on another, and which session is sitting on a prompt for you.&lt;/p&gt;

&lt;p&gt;I build &lt;a href="https://github.com/Atoll92/agent-standup" rel="noopener noreferrer"&gt;Agent Standup&lt;/a&gt;, an open-source tool that reads those files and plays each session back as a live call. This article is what I learned reading them: where each tool keeps its sessions, which records matter, how sub-agents show up, and how to keep a reader correct when a format you don't control changes under you. Everything here is read-only: the reader never writes in these folders and never calls a model.&lt;/p&gt;

&lt;p&gt;The formats below were checked against real sessions in October 2026: Claude Code 2.1, Codex (desktop app and CLI), and Mistral Vibe 2.26.1. They are undocumented, so treat every field name as something that can change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code: one JSONL file per session
&lt;/h2&gt;

&lt;p&gt;Claude Code keeps each session in &lt;code&gt;~/.claude/projects/&amp;lt;folder&amp;gt;/&amp;lt;session-id&amp;gt;.jsonl&lt;/code&gt;. The folder is the project's path with every character that isn't a letter or a digit turned into &lt;code&gt;-&lt;/code&gt;, so &lt;code&gt;/Users/me/shop-api&lt;/code&gt; becomes &lt;code&gt;-Users-me-shop-api&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each line is one JSON record, and its &lt;code&gt;type&lt;/code&gt; says what it is. &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;assistant&lt;/code&gt; records carry the conversation. Others you'll meet: &lt;code&gt;custom-title&lt;/code&gt; and &lt;code&gt;ai-title&lt;/code&gt; (the session's name), &lt;code&gt;system&lt;/code&gt;, &lt;code&gt;attachment&lt;/code&gt;, &lt;code&gt;queue-operation&lt;/code&gt;, &lt;code&gt;pr-link&lt;/code&gt; and &lt;code&gt;result&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;An assistant message holds a list of content blocks: &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;thinking&lt;/code&gt; and &lt;code&gt;tool_use&lt;/code&gt; (a tool name, an id and its input). A trimmed example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2026-10-15T09:12:03.120Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"msg_01…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"stop_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"tool_use"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"output_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;340&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"cache_read_input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;20480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"cache_creation_input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:[{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"tool_use"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"toolu_01…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"input"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"npm test"&lt;/span&gt;&lt;span class="p"&gt;}}]}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool's answer comes back in a later &lt;code&gt;user&lt;/code&gt; record, as a &lt;code&gt;tool_result&lt;/code&gt; block with the same &lt;code&gt;tool_use_id&lt;/code&gt;. Claude Code often writes a structured &lt;code&gt;toolUseResult&lt;/code&gt; beside it too, which holds what the text doesn't: a published artifact's link and id, for example.&lt;/p&gt;

&lt;p&gt;What tripped me up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Token usage is repeated.&lt;/strong&gt; The same assistant message is written once per content block, each time with identical &lt;code&gt;usage&lt;/code&gt; numbers. Count usage once per &lt;code&gt;message.id&lt;/code&gt;, or a message with five blocks costs five times as much.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The end of a turn is a mark, not a silence.&lt;/strong&gt; The lead's last message of a turn has &lt;code&gt;stop_reason: "end_turn"&lt;/code&gt;. Until that mark arrives, the lead is still working, even if nothing has been written for a minute. Pressing Esc shows up instead as a user message starting with &lt;code&gt;[Request interrupted&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not everything in a user record was typed.&lt;/strong&gt; User messages also carry &lt;code&gt;&amp;lt;system-reminder&amp;gt;&lt;/code&gt; blocks, slash-command and task-notification wrappers, &lt;code&gt;isMeta&lt;/code&gt; records and the summary written after a compaction. Filter them out before showing "what you said".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sub-agents have their own files.&lt;/strong&gt; The lead starts one with the &lt;code&gt;Agent&lt;/code&gt; tool (&lt;code&gt;Task&lt;/code&gt; in older versions), and each sub-agent writes its own transcript in &lt;code&gt;&amp;lt;session-id&amp;gt;/subagents/*.jsonl&lt;/code&gt;. Agents launched by a workflow go one folder deeper, in &lt;code&gt;subagents/workflows/&amp;lt;run&amp;gt;/agent-*.jsonl&lt;/code&gt;. A sub-agent's first user message is its order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sub-agents changed how they report.&lt;/strong&gt; Since Claude Code 2.1.293 a sub-agent hands its report back through a &lt;code&gt;SubagentHandback&lt;/code&gt; tool call, and often writes no final text of its own. A reader that only looks at text blocks silently loses every report.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Codex: one rollout file per thread
&lt;/h2&gt;

&lt;p&gt;Codex, both the desktop app and the &lt;code&gt;codex&lt;/code&gt; CLI, writes one "rollout" file per thread in &lt;code&gt;~/.codex/sessions/YYYY/MM/DD/rollout-&amp;lt;time&amp;gt;-&amp;lt;thread-id&amp;gt;.jsonl&lt;/code&gt; (or under &lt;code&gt;$CODEX_HOME&lt;/code&gt;). Thread names live separately, in &lt;code&gt;session_index.jsonl&lt;/code&gt;. You don't need anything else from the Codex folder.&lt;/p&gt;

&lt;p&gt;The first line of every rollout is a &lt;code&gt;session_meta&lt;/code&gt; record, and it carries the fields that tell you what the thread is: &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;cwd&lt;/code&gt;, &lt;code&gt;cli_version&lt;/code&gt;, &lt;code&gt;originator&lt;/code&gt;, &lt;code&gt;source&lt;/code&gt; and, for a child thread, &lt;code&gt;parent_thread_id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"session_meta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"01a1…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/Users/me/shop-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"cli_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"subagent"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nl"&gt;"other"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"guardian"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="nl"&gt;"parent_thread_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"01a0…"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;source&lt;/code&gt; sorts threads.&lt;/strong&gt; A thread you started has a plain string (&lt;code&gt;"vscode"&lt;/code&gt; in my sessions). A sub-agent has an object, &lt;code&gt;{"subagent": {...}}&lt;/code&gt;, and its parent is in &lt;code&gt;parent_thread_id&lt;/code&gt;. Link children to parents with that, never with file names or times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most sub-agent threads aren't yours.&lt;/strong&gt; On my machine, 34 of 57 rollouts were &lt;code&gt;{"subagent":{"other":"guardian"}}&lt;/code&gt;: the short automatic reviews Codex runs before some commands. Showing them as sessions floods the list, so I hide them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There is an official way to ask for the same lineage.&lt;/strong&gt; Codex's App Server API (the JSON-RPC interface its IDE integrations use) can list a thread's children with &lt;code&gt;thread/list&lt;/code&gt; and the filters &lt;code&gt;sourceKinds: ["subAgentThreadSpawn"]&lt;/code&gt; and &lt;code&gt;parentThreadId&lt;/code&gt;, behind its experimental flag. It means running a Codex process, though; reading &lt;code&gt;session_meta&lt;/code&gt; gets you the same link with no process at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A command appears when it finishes.&lt;/strong&gt; Codex writes a command down once it's done, with its output and exit status, so a live view shows it after the fact, not while it runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What maps cleanly&lt;/strong&gt; to a common timeline: your prompts, the agent's messages, commands with their output, file changes, web searches, MCP calls, the questions it asks you, reasoning summaries, token counts and the end of each turn.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mistral Vibe: two engines, two formats
&lt;/h2&gt;

&lt;p&gt;Vibe keeps its sessions in &lt;code&gt;~/.vibe/logs/session&lt;/code&gt; (or under &lt;code&gt;$VIBE_HOME&lt;/code&gt;), and since version 2.26 it writes them in two different ways depending on the engine. A reader has to handle both, because people still run the old one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The current engine&lt;/strong&gt; (the default in 2.26) writes &lt;code&gt;logs/session/unified/&amp;lt;id&amp;gt;/&lt;/code&gt;, and it works like an event-sourced store:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;CURRENT&lt;/code&gt; names the latest snapshot, which Vibe calls a generation.&lt;/li&gt;
&lt;li&gt;That generation's manifest lists the pages of history (&lt;code&gt;chunks/&amp;lt;sha&amp;gt;.json&lt;/code&gt;, each an array of entries) and the journal that follows them (&lt;code&gt;journal/&amp;lt;n&amp;gt;.jsonl&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Each journal line is a &lt;code&gt;projection_delta&lt;/code&gt; that appends, replaces or removes entries, until the next snapshot.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So reading a session means loading the snapshot's chunks, then replaying the journal in order. An entry is a message (yours or the agent's), a piece of reasoning, or an "effect": a tool call with its input, its state, its result, and the times it started and ended. Every event has its time, so a replay is exact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sub-agents leave no history of their own&lt;/strong&gt; in this engine. All you know about one is what the lead did with it: &lt;code&gt;subagent.spawn&lt;/code&gt;, &lt;code&gt;.send_message&lt;/code&gt;, &lt;code&gt;.wait&lt;/code&gt; (with the answer it got back) and &lt;code&gt;.stop&lt;/code&gt;. You can show who was asked what and what they answered, but not each of their commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The earlier engine&lt;/strong&gt; (&lt;code&gt;vibe --legacy-harness&lt;/code&gt;, and older versions) writes &lt;code&gt;&amp;lt;prefix&amp;gt;_&amp;lt;date&amp;gt;_&amp;lt;time&amp;gt;_&amp;lt;id&amp;gt;/&lt;/code&gt; with a &lt;code&gt;messages.jsonl&lt;/code&gt; (one message per line) and a &lt;code&gt;meta.json&lt;/code&gt;. Each sub-agent is a session of its own in an &lt;code&gt;agents/&lt;/code&gt; folder inside it, so here you do see a sub-agent's commands. The catch: no message has a timestamp, and the file is saved at the end of each step. Followed live, times are right to within a step; read afterwards, you have to spread the events between the session's start and end.&lt;/p&gt;

&lt;p&gt;Two more details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vibe records when it's waiting for you,&lt;/strong&gt; for an approval or an answer, so a reader can mark that session as "needs you" without guessing from silence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The location can move:&lt;/strong&gt; &lt;code&gt;session_logging.save_dir&lt;/code&gt; in Vibe's settings sends logs somewhere else, so let users point the reader at another folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One event list for three tools
&lt;/h2&gt;

&lt;p&gt;[embedded content: How Agent Standup reads three tools: three formats, three adapters, one event list, four views]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F81znuht9433gjhzvsq93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F81znuht9433gjhzvsq93.png" alt=" " width="799" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each adapter has a small job: turn its tool's records into the same handful of events (something said, something typed, tool calls, their results, token usage, the end of a turn, a compaction). Everything after that is shared: the live call, the board of sessions, the sub-agent tree and the replay. Supporting a fourth tool means writing one adapter, not four features.&lt;/p&gt;

&lt;p&gt;The reader is incremental. Each file is parsed once, then only the bytes appended since the last read: the reader keeps an offset per file, plus the last bytes it read. If those bytes are no longer where they were, the file was rewritten rather than appended to, and it's read again from the start. A session is the merge of its main file and one file per sub-agent, each cached on its own, so following a busy session costs a few small reads every couple of seconds, not a full parse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Staying correct when the formats change
&lt;/h2&gt;

&lt;p&gt;Three tools, no documentation, and each ships often. What kept the reader honest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write each adapter against real files,&lt;/strong&gt; never against a guess or a blog post. Then keep a few anonymised samples as test fixtures, so a broken assumption fails a test instead of a user's screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diff the old and new versions on real sessions before every release.&lt;/strong&gt; I run the previous release and the candidate side by side, each as its own process, on the roughly 120 sessions on my machine, and compare every API response. For the last release that was 76,943 events, all identical except for the changes I meant to make. The test suite didn't catch everything this catches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolate the readers.&lt;/strong&gt; One odd Vibe session once took the whole session list down, for every tool, and only an adversarial review before the release caught it. Now each reader other than Claude Code's runs inside a guard: a file it can't read costs one session, not all of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expect new fields to change meaning.&lt;/strong&gt; The &lt;code&gt;SubagentHandback&lt;/code&gt; call (Claude Code 2.1.293) didn't break anything visibly; sub-agents just stopped reporting back in the call. Silent changes like that only show up when you compare against real sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never write in the tools' folders.&lt;/strong&gt; A reader that only reads can't corrupt a session, and users trust it with their history.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it, and help fill the gaps
&lt;/h2&gt;

&lt;p&gt;Agent Standup is free and MIT licensed. It's plain Node with no runtime dependencies, and it runs as a VS Code extension (also on Open VSX for Cursor and VSCodium), a terminal command, a desktop app or a Claude Code plugin. To try it with a built-in demo, no install needed (Node 18 or later):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @double_geste/agent-standup &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The adapters are in the repo (&lt;a href="https://github.com/Atoll92/agent-standup/blob/main/codex.js" rel="noopener noreferrer"&gt;&lt;code&gt;codex.js&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://github.com/Atoll92/agent-standup/blob/main/vibe.js" rel="noopener noreferrer"&gt;&lt;code&gt;vibe.js&lt;/code&gt;&lt;/a&gt;, and the Claude Code reader in &lt;a href="https://github.com/Atoll92/agent-standup/blob/main/server.js" rel="noopener noreferrer"&gt;&lt;code&gt;server.js&lt;/code&gt;&lt;/a&gt;), if you want to reuse the parsing for something else.&lt;/p&gt;

&lt;p&gt;Three gaps where real sample files would help, with ids and paths redacted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Codex rollout where Codex spawned a sub-agent for a task (just its &lt;code&gt;session_meta&lt;/code&gt; line);&lt;/li&gt;
&lt;li&gt;a Vibe session from the current engine where a sub-agent's own steps are kept anywhere;&lt;/li&gt;
&lt;li&gt;sessions from Gemini CLI or OpenCode, the next tools worth reading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Issues and samples are welcome at &lt;a href="https://github.com/Atoll92/agent-standup" rel="noopener noreferrer"&gt;github.com/Atoll92/agent-standup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Not affiliated with Anthropic, OpenAI or Mistral AI.&lt;/em&gt;&lt;/p&gt;

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