会话持久化
Deep Code 会把每个项目的会话记录保存在本机用户目录中。会话历史用于 /resume、/continue 和 /undo,不依赖当前终端进程是否仍在运行。
存储位置
每个项目都有独立的存储目录:
~/.deepcode/projects/<project-code>/<project-code> 由项目根目录路径生成。普通路径会转换为安全的目录名;路径过长时,Deep Code 会保留项目名的一部分,并追加稳定哈希,以避免存储路径过长。
项目存储目录包含以下主要文件和目录:
| 路径 | 说明 |
|---|---|
sessions-index.json | 当前项目的会话索引,保存会话列表和每个会话的概要信息。 |
<session-id>.jsonl | 单个会话的消息记录。每一行是一条 JSON 格式的消息。 |
file-history/.git | 用于代码快照的内部 Git 仓库,供 /undo 恢复文件内容。 |
持久化内容
会话索引
sessions-index.json 保存最近的会话条目。每个条目包含:
- 会话 ID、标题、创建时间和更新时间。
- 会话状态,例如
pending、processing、completed、failed、interrupted、ask_permission、waiting_for_user。 - 最近一次 assistant 回复、思考内容、拒绝原因和失败原因。
- 最近一次工具调用信息、token 用量和活跃 token 数。
- 当前会话中仍被跟踪的子进程信息。
会话标题默认来自首次用户输入的前 100 个字符。使用会话列表中的重命名功能会更新索引里的标题。
消息文件
每个会话有一个独立的 JSONL 消息文件,文件名是 <session-id>.jsonl。消息按追加顺序写入,常见字段包括:
| 字段 | 说明 |
|---|---|
id | 消息 ID。 |
sessionId | 所属会话 ID。 |
role | 消息角色:system、user、assistant 或 tool。 |
content | 文本内容。 |
contentParams | 结构化内容,例如图片输入。 |
messageParams | 模型消息参数,例如 tool call ID、tool calls、reasoning content。 |
visible | 是否在界面中显示。 |
compacted | 是否已经被长会话压缩替代。 |
checkpointHash | 与 /undo 关联的代码快照哈希。 |
meta | 工具展示、skill、权限、摘要等附加信息。 |
读取消息文件时,Deep Code 会逐行解析 JSON;无法解析的行会被忽略,以便尽量保留其余可用历史。
代码快照
Deep Code 使用 file-history/.git 保存代码快照。这个仓库只作为内部文件历史使用,不是项目仓库本身。
- 新会话会初始化一条以会话 ID 命名的内部分支。
- 每次用户输入前,会记录已跟踪文件的状态。
- 工具修改文件前后,会按需记录相关文件的状态。
- 用户消息上的
checkpointHash用来把某次对话位置和对应的代码状态关联起来。
快照只覆盖 Deep Code 已跟踪到的文件;无关文件不会因为 /undo 被任意改写。
会话生命周期
创建会话
创建新会话时,Deep Code 会:
- 生成新的会话 ID。
- 初始化该会话的代码快照分支。
- 在
sessions-index.json中添加会话条目。 - 写入系统提示、运行时上下文、项目指令和用户消息。
- 启动模型请求,并在 assistant 回复和工具执行过程中持续更新索引和消息文件。
项目级会话列表最多保留最近 50 条记录。超过上限时,较旧会话会从索引中移除,其消息文件和相关运行时资源也会被清理。
继续会话
/resume 会显示当前项目的历史会话列表,并选择一个会话继续。
/continue 会优先继续当前活动会话;如果没有可继续的活动会话,则进入历史会话选择流程。
继续会话时,Deep Code 会读取会话消息文件,过滤已压缩的旧消息,修复未完成的工具调用上下文,并把可用历史转换为模型请求消息。
长会话压缩
当会话上下文过长时,Deep Code 会触发压缩流程:
- 选取较早的一段非系统消息生成摘要。
- 将这段旧消息标记为
compacted: true。 - 在消息序列中插入一条不可见的系统摘要消息。
后续请求只会使用未压缩消息和摘要消息。原始消息仍保留在 JSONL 文件中,用于审计和界面历史展示。
中断、失败和权限等待
会话状态会随运行过程更新:
- 用户中断后,状态会变为
interrupted,并清理当前会话控制器和被跟踪的子进程。 - 请求失败时,状态会变为
failed,失败原因写入索引。 - 工具调用需要确认时,状态会变为
ask_permission。 - 工具需要用户输入时,状态会变为
waiting_for_user。
这些状态都会持久化到 sessions-index.json,因此重新打开 CLI 后仍能在会话列表中看到。
/undo 如何使用持久化数据
/undo 的候选项来自可见且未压缩的用户消息。每个候选项会检查是否有关联的 checkpointHash,并确认对应快照是否可恢复。
根据选择,Deep Code 可以执行以下操作:
| 操作 | 行为 |
|---|---|
| 恢复对话 | 截断所选用户消息之前的消息历史,并更新索引中的最新 assistant 信息。 |
| 恢复代码 | 从 file-history/.git 中读取所选快照,并还原被跟踪文件。 |
| 同时恢复 | 先恢复代码,再截断对话历史。 |
恢复对话会重写该会话的 JSONL 文件;恢复代码会修改工作区中被快照跟踪的文件。
删除和重命名
在会话列表中删除会话会:
- 从
sessions-index.json移除该条目。 - 删除对应的
<session-id>.jsonl文件。 - 清理该会话的内存状态、临时工作目录状态、控制器和仍被跟踪的进程控制信息。
重命名会话只更新索引中的 summary 字段,不会改动消息文件或代码快照。
注意事项
- 会话数据保存在本机用户目录下,并按项目分隔。
- 移动项目目录后,新的项目根路径会生成新的
<project-code>;旧路径对应的历史不会自动迁移。 file-history/.git是 Deep Code 的内部快照仓库,不应手动修改。- 会话删除不会清理内部 Git 仓库中的所有历史对象;它主要删除会话索引、消息文件和运行时资源。