详解 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:
| 字段 | 类型 | 说明 |
|---|---|---|
key | TEXT | workspace 绝对路径(如 /home/user/my-project) |
conversation_id | TEXT | session UUID |
value | TEXT | 完整对话 JSON(长时间会话可达数十 MB),Strands Agent 内部格式 |
created_at | INTEGER | 创建时间(毫秒时间戳) |
updated_at | INTEGER | 更新时间(毫秒时间戳) |
同一个 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 -l | SQLite + JSON | 同时列出 v1 和 v2 session,同 ID 可能出现两条 |
kiro-cli chat -r | SQLite + 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 变化
| v1 | v2 (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 中数据完好。修复方法:
kiro-cli chat -l找到目标 session ID(v1 记录)kiro-cli chat --resume-id <session_id>指定 ID 加载- 加载成功后自动迁移为 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 记录进行清理