详解 Kiro CLI Session 存储机制

背景

日常使用 kiro-cli 时,chat -r 恢复对话、chat -l 查看历史,这些操作背后的数据是怎么存的?为什么升级到 kiro-cli 2.0 后同一个workspace下的 session 有的显示 v1 有的显示 v2?为什么升级后偶尔会遇到 "Session not found"的问题?

带着这些问题,我们通过实际测试和文件系统分析,把 kiro-cli 的 session 存储机制完整梳理了一遍。

 

 

测试环境:基于 kiro-cli 2.0.0,后续版本行为可能变化。

Session 存储机制详解

概述

kiro-cli 使用两套并行的存储系统管理 session,通过 cwd(当前工作目录)关联 session 和 workspace:

存储位置格式用途
SQLite~/.local/share/kiro-cli/data.sqlite3状态快照chat 模式主存储,v2 ACP 双写
JSON 文件~/.kiro/sessions/cli/{session_id}.*事件溯源ACP 模式主存储

SQLite 存储

conversations_v2

字段类型说明
keyTEXTworkspace 绝对路径(如 /home/user/my-project
conversation_idTEXTsession UUID
valueTEXT完整对话 JSON(长时间会话可达数十 MB),Strands Agent 内部格式
created_atINTEGER创建时间(毫秒时间戳)
updated_atINTEGER更新时间(毫秒时间戳)

同一个 cwd 可以有多个 session(历史记录)。

value 内部结构(状态快照模型):

{
  "conversation_id": "...",
  "history": [...],              // 对话历史
  "transcript": [...],           // 完整对话记录
  "tools": {...},                // 工具配置
  "context_manager": {...},      // 上下文管理状态
  "latest_summary": "...",       // 摘要
  "model_info": {...},           // 模型信息
  "file_line_tracker": {...},
  "checkpoint_manager": {...}
}

JSON 文件存储

每个 session 三个文件:

{session_id}.json — metadata + 权限 + 状态:

{
  "session_id": "uuid",
  "cwd": "/absolute/path/to/workspace",
  "created_at": "2026-04-14T08:00:55Z",
  "updated_at": "2026-04-17T09:57:19Z",
  "title": "对话标题(首条消息摘要)",
  "exported_from_v1": true,
  "session_state": {
    "version": "...",
    "conversation_metadata": { "user_turn_metadatas": [...] },
    "permissions": {
      "filesystem": { "allowed_read_paths": [...], "allowed_write_paths": [...] },
      "trusted_tools": [...],
      "allowed_commands": [...]
    },
    "agent_name": "kiro_default"
  }
}

{session_id}.jsonl — 对话事件流(每行一个事件):

{"version": "v1", "kind": "Prompt", "data": {"message_id": "...", "content": [...]}}
{"version": "v1", "kind": "AssistantMessage", "data": {"message_id": "...", "content": [...]}}
{"version": "v1", "kind": "ToolUse", "data": {...}}

{session_id}.lock — 进程锁(不能为空,否则报 EOF while parsing a value):

{"pid": 12345, "started_at": "2026-04-16T06:05:52Z"}

命令与查找逻辑

所有命令基于 cwd 匹配 session(SQLite 的 key 字段 / JSON 的 cwd 字段):

命令查找范围说明
kiro-cli chat -lSQLite + JSON同时列出 v1 和 v2 session,同 ID 可能出现两条
kiro-cli chat -rSQLite + JSON取当前 cwd 下最近更新的 session
kiro-cli chat --resume-id <id>SQLite + JSON指定 ID 加载,v2 JSON 优先于 v1 SQLite
session/new传入 cwd,创建新 session,同时写 JSON + SQLite
session/load传入 sessionId + cwd,按 id 查找

v1 vs v2 变化


v1v2 (2.0+)
chat → SQLite
ACP → JSON
ACP → SQLite✅ (双写)
ACP load chat session❌ (Session not found)
chat resume ACP session
.lock 冲突不存在(存储隔离)存在(需释放锁)

v2 在内部做了格式转换(SQLite 状态快照 ↔ JSON 事件流),对外透明。

v1 → v2 自动迁移:当通过 -r--resume-id 加载 v1 session(仅存在于 SQLite)时,kiro-cli 自动生成 JSON + jsonl 文件,将其迁移为 v2 格式。迁移后 -l 中该 session 标记从 v1 变为 v2,同时 SQLite 中的 v1 记录仍保留(短暂出现同 ID 两条记录)。exported_from_v1: true 标记表示该 session 从 v1 格式迁移而来。

故障排查

执行 kiro-cli chat -r 报 "Session not found"

大版本升级或者一些特殊原因可能导致 -r 无法找到 v1 session,即使 SQLite 中数据完好。修复方法:

  1. kiro-cli chat -l 找到目标 session ID(v1 记录)
  2. kiro-cli chat --resume-id <session_id> 指定 ID 加载
  3. 加载成功后自动迁移为 v2 格式,后续 -r 恢复正常

--resume-id 加载到空 session

当同一 session ID 同时存在 v2 JSON(0 msgs 空壳)和 v1 SQLite(有数据)时,--resume-id 优先加载 v2 JSON。退出时 kiro-cli 自动清理 0 msgs 的空 JSON 文件,之后再 resume 即可 fallback 到 v1 SQLite。

lock 文件错误

lock 文件不能为空,否则报 EOF while parsing a value 错误。正确格式:{"pid": <进程号>, "started_at": "<ISO时间>"}

注意事项

  • 进程锁:同一 session 不能被 chat 和 ACP 同时持有,需在切换前释放 .lock 文件
  • 存储增长:截至 kiro-cli 2.x,尚未提供内置清理工具。SQLite 文件会随 session 数量增长(百级 sessions 可达数百 MB),用户可手动删除 ~/.kiro/sessions/cli/ 下的旧 session 文件和对应的 SQLite 记录进行清理
Previous Post
No Comment
Add Comment
comment url