三、REPL initialMessages 来源
initialMessages 是 REPL 组件 prop,由 main.tsx 根据启动模式注入:
| # | 启动模式 | 来源 | 位置 |
|---|---|---|---|
| 1 | Session Resume (--continue) | loaded.messages — 从 JSONL 文件反序列化 | 3141 |
| 2 | claude connect <url> | [connectInfoMessage] — system info | 3184 |
| 3 | claude ssh <host> | [sshInfoMessage] — system info | 3250 |
| 4 | claude assistant <id> | [infoMessage] — system info | 3346 |
| 5 | --remote 模式 | [remoteInfoMessage] 或 [remoteInfoMessage, initialUserMessage] | 3495 |
| 6 | 交互式 Resume 选择器 | resumeData.messages | 3740 |
| 7 | 全新会话 | [deepLinkBanner, ...hookMessages] / hookMessages / undefined | 3797 |
全新会话的组成:
hookMessages(main.tsx:2449)— SessionStart hooks 产生的消息deepLinkBanner(main.tsx:3780-3795)— Deep link provenance 警告- 若 hooks 还在执行,通过
pendingHookMessagesprop 异步等待
四、聊天历史存储与清理
存储路径
~/.claude/projects/<sanitized-cwd-path>/<sessionId>.jsonl
| 层级 | 函数 | 示例 |
|---|---|---|
getClaudeConfigHomeDir() | envUtils.ts:7 | ~/.claude 或 $CLAUDE_CONFIG_DIR |
getProjectsDir() | sessionStorage.ts:198 | ~/.claude/projects |
getProjectDir(cwd) | sessionStorage.ts:436 | ~/.claude/projects/<sanitized-path> |
getTranscriptPath() | sessionStorage.ts:202 | .../<sessionId>.jsonl |
文件格式
JSONL(每行一个 JSON 对象),包含:
TranscriptMessage— 用户/助手/系统消息ContentReplacementEntry— 内容替换记录FileHistorySnapshotMessage— 文件历史快照- 元数据:
custom-title、tag、agent-name、last-prompt等
写入机制
- 每轮消息通过
recordTranscript()→Project.insertMessageChain()→appendEntry()→ 异步队列 →fsAppendFile()实时追加 - 刷新间隔:
FLUSH_INTERVAL_MS = 100ms - 首个 user/assistant 消息时
materializeSessionFile()创建文件,此前消息暂存pendingEntries内存
清理机制
cleanupOldMessageFilesInBackground()(cleanup.ts:575)异步执行:
const DEFAULT_CLEANUP_PERIOD_DAYS = 30 // 可通过 settings.cleanupPeriodDays 配置
清理范围:
- 会话 JSONL 文件(按
mtime > 30天删除) - 关联 tool-results 目录
- Plan 文件、debug 日志、file-history 备份、image cache、session-env 等
模型请求的消息范围
| 场景 | 消息来源 | 是否包含历史会话 |
|---|---|---|
| 全新启动 | 空消息列表 | 否 |
/clear 后 | 空消息列表 | 否 |
/resume <sessionId> | 对应 JSONL 反序列化 | 是(接续该会话) |
--continue / --resume 启动 | 上次会话 JSONL | 是(接续上次会话) |
关键机制: /clear 执行 setMessages(() => []) + regenerateSessionId(),新 sessionId 对应的 queryLoop 消息从空开始。JSONL 文件仅用于持久化和 resume,不会自动注入到模型上下文中。