$ cat zh/guides/claude-code-transcript-jsonl

Claude Code Transcript JSONL 应该怎样读取

按事件外壳、身份和语义顺序读取 Claude Code transcript,避免把每条 assistant 记录都误判为完成。

Claude Code transcript 是有价值的本地证据,但它并不是一串结构完全相同的聊天消息。每一行都是独立 JSON 对象,必须结合顶层类型和嵌套字段理解,不能看到某个关键词就直接宣布会话结束。

先处理事件外壳

读取时应该逐行解析。空行、尚未写完的尾行或格式错误的记录只跳过当前一行,不能让整个扫描失败。文件仍在增长时,当前不完整的最后一行可能在下一次文件变化后变成有效事件。

Agent Island 判断 Claude 活动时会用到 typeuuidtimestampmessage.stop_reasonisSidechainisApiErrorMessagetoolEndsTurn。并不是每行都有所有字段;字段缺失时应保持未知,而不是补造状态。

逐行读取
  空行 -> 跳过
  JSON 解析失败 -> 跳过当前行
  只根据真实存在的字段分类

区分用户活动和 assistant 输出

用户事件说明后续回合已经开始。assistant 输出说明模型产生了内容,却不自动代表整个会话结束。解析器必须保留事件顺序,让更晚的用户事件或开始事件覆盖之前的完成候选。

uuid 和语义时间戳用于保留事件身份与顺序。不能只用文件修改时间替代,因为文件时间描述的是容器,事件时间描述的是单条记录。

Sidechain 不是主线程交接

isSidechain 标记的活动不能直接当作主线程需要用户处理的交接。后台子 Agent 可能已经完成,但父会话仍在继续。两者触发相同前台提醒,会让用户过早返回。

因此,在产生 needs-you 提醒前要先排除 sidechain 完成事件。它们仍可用于诊断,但不等于主线程交接。

API 错误不能冒充完成

assistant 形态的事件也可能承载 API 错误或限流信息。isApiErrorMessage 是必要门禁:错误应进入对应错误状态,不能算作成功完成。

同样,message.stop_reasontoolEndsTurn 也必须结合上下文。停止标记可能只描述一次模型响应,并不能证明后面没有工具、用户或新开始事件。

应该重建状态,而不是搜索关键词

可靠读取流程是:解析有效记录、保留事件身份和语义时间、排除 sidechain 前台提醒、单独处理 API 错误,最后确认完成候选没有被更晚活动覆盖。

这也是为什么直接搜索 stop_reasoncompleted 不够。关键词没有回合身份、顺序规则和错误门禁。

隐私边界

Agent Island 在本机读取 transcript 来重建状态,不会把会话内容上传到 Agent Island 服务。本文描述的是 v1.7.1 开源代码中可核验的已发布行为,不代表所有未来 Claude Code transcript 都永远使用完全相同的 schema。