Source Bundle

claude code 证据页

来自 docs/claude code 的原始分析文档与行号。

证据页
怎么用这页
  • 左上角是文档名,下面是带行号的原始内容。
  • 学习页里的源码锚点会跳到这里的具体行号。
Docs

原始文档与行号

这些内容直接来自当前仓库的 docs/。

claude code.md
`claude code`
1
# `claude code`
2
3
## 仓库定位
4
5
`claude code` 不是单一 memory 模块,而是把 `context`、跨会话文件型 memory、单会话摘要 memory、transcript/history、压缩链路组合在一起的终端型 agent runtime。本组文档只基于源码,不复述项目说明。
6
7
## 源码架构树
8
9
```text
10
claude code
11
├─ context.ts
12
│ ├─ getSystemContext()
13
│ └─ getUserContext()
14
├─ constants/prompts.ts
15
│ └─ loadMemoryPrompt() 动态系统提示片段
16
├─ memdir/
17
│ ├─ paths.ts
18
│ ├─ memdir.ts
19
│ └─ teamMemPaths.ts
20
├─ utils/claudemd.ts
21
│ └─ memory 文件发现、去重、include、过滤
22
├─ services/SessionMemory/
23
│ ├─ sessionMemory.ts
24
│ └─ prompts.ts
25
├─ commands/compact/
26
├─ utils/sessionStorage.ts
27
└─ history.ts / assistant/sessionHistory.ts
28
```
29
30
## 关键结论摘要
31
32
- 本仓库至少有三条不同但相关的链路:`context` 组装、`memdir/claudemd` 文件型 memory、`SessionMemory` 单会话摘要;三者不能混成一套“memory 系统”。
33
- `getSystemContext()` 与 `getUserContext()` 都是 session 级缓存;`/compact` 会清用户上下文缓存,迫使压缩后重新组装可见上下文。
34
- `memdir` 的长期记忆落在 `~/.claude/projects/<repo>/memory/` 一类路径下,而 `SessionMemory` 则固定落在当前 session 目录里的 `session-memory/summary.md`。
35
- `/context` 展示的不是 UI 原始消息,而是经过 compact boundary 裁剪、API 映射和 memory 注入后“模型实际看到的上下文视图”。
36
37
## 专题文档
38
39
- [01-架构与范围](./claude%20code/01-%E6%9E%B6%E6%9E%84%E4%B8%8E%E8%8C%83%E5%9B%B4.md)
40
- [02-context管理](./claude%20code/02-context%E7%AE%A1%E7%90%86.md)
41
- [03-memory实现](./claude%20code/03-memory%E5%AE%9E%E7%8E%B0.md)
42
- [04-存储与状态](./claude%20code/04-%E5%AD%98%E5%82%A8%E4%B8%8E%E7%8A%B6%E6%80%81.md)
43
- [05-调用链、压缩与边界](./claude%20code/05-%E8%B0%83%E7%94%A8%E9%93%BE%E3%80%81%E5%8E%8B%E7%BC%A9%E4%B8%8E%E8%BE%B9%E7%95%8C.md)
44
45
## 关键源码索引
46
47
- `context.ts:29-155`
48
- `constants/prompts.ts:476-495`
49
- `utils/claudemd.ts:229-1153`
50
- `memdir/memdir.ts:199-419`
51
- `memdir/paths.ts:223-257`
52
- `services/SessionMemory/sessionMemory.ts:183-387`
53
- `services/SessionMemory/prompts.ts:86-256`
54
- `commands/compact/compact.ts:46-117`
55
- `utils/sessionStorage.ts:202-202`
56
- `history.ts:114-114`
57
58
## 阅读提示
59
60
先看 `02-context管理`,再读 `03-memory实现`。如果先从 `history.ts` 开始,很容易把命令历史误当成对话 memory。
61
claude code/01-架构与范围.md
`claude code`:架构与范围
1
# `claude code`:架构与范围
2
3
## 1. 总体分层
4
5
这套实现至少分成四层:
6
7
- `context`:决定本轮真正送进模型的系统上下文和用户上下文。
8
- `memdir / claudemd`:负责跨会话文件型 memory,包括 `MEMORY.md`、daily log、team memory、`CLAUDE.md` 系列文件发现与拼接。
9
- `SessionMemory`:负责当前 session 的结构化摘要文件 `summary.md`。
10
- `history / transcript / compact`:负责历史记录、压缩边界、会话落盘和远端事件分页。
11
12
### 源码锚点
13
14
- `context.ts:29-155`
15
- `utils/claudemd.ts:229-1153`
16
- `memdir/memdir.ts:199-419`
17
- `services/SessionMemory/sessionMemory.ts:183-387`
18
- `history.ts:114-114`
19
20
## 2. 范围边界
21
22
本组文档重点覆盖:
23
24
- `context.ts`
25
- `constants/prompts.ts`
26
- `utils/claudemd.ts`
27
- `memdir/*`
28
- `services/SessionMemory/*`
29
- `commands/compact/*`
30
- `utils/sessionStorage.ts`
31
32
不把纯 UI 展示逻辑当成 memory 实现,也不把命令历史等同于对话记忆。
33
34
### 源码锚点
35
36
- `constants/prompts.ts:476-495`
37
- `commands/context/context.tsx:18-18`
38
- `commands/memory/memory.tsx:86-86`
39
- `utils/sessionStorage.ts:202-202`
40
41
## 3. 关键边界判断
42
43
- `memdir` 是跨会话、项目级的文件型 memory。
44
- `SessionMemory` 是当前 session 的摘要文件,不等于长期 memory。
45
- `history.ts` 记录的是命令历史,不是会话级语义记忆。
46
- `/context` 展示的是 API 视角上下文,而不是原始 UI 消息数组。
47
48
### 源码锚点
49
50
- `memdir/paths.ts:223-257`
51
- `services/SessionMemory/sessionMemory.ts:272-387`
52
- `history.ts:114-114`
53
- `utils/analyzeContext.ts:272-320`
54
- `utils/analyzeContext.ts:918-964`
55
claude code/02-context管理.md
`claude code`:context 管理
1
# `claude code`:context 管理
2
3
## 1. System / User Context 的组装与缓存
4
5
`getSystemContext()` 与 `getUserContext()` 都是 session 级 memoize。前者主要负责系统上下文,例如 git 状态和可选 cache-breaker;后者负责用户侧上下文,包括 `CLAUDE.md` 系列文件、memory files 和日期信息。
6
7
`setSystemPromptInjection()` 会主动失效系统上下文缓存,而压缩链路也会清 `getUserContext()` 的缓存,保证 compact 后的上下文不会继续沿用旧注入结果。
8
9
### 源码锚点
10
11
- `context.ts:29-29`
12
- `context.ts:116-155`
13
- `context.ts:155-155`
14
15
## 2. Memory 作为动态系统提示片段注入
16
17
`constants/prompts.ts` 里的 `loadMemoryPrompt()` 才是 memory 进入系统提示的真正入口。这里的 memory 不是固定常量,而是每轮可重算的动态 prompt section,因此它和 session 级缓存边界一起决定“什么时候重建模型可见上下文”。
18
19
### 源码锚点
20
21
- `constants/prompts.ts:476-495`
22
23
## 3. `/context` 展示的是 API 视图
24
25
`/context` 命令不是直接打印 UI 历史。它会先通过 `getMessagesAfterCompactBoundary()` 截掉 compact boundary 之前的消息,再做 `projectView` 与 `microcompactMessages()` 转换,最后由 `analyzeContextUsage()` 重新统计 system prompt、memory files、messages 和 token 使用量。
26
27
因此 `/context` 的意义是“当前这轮真正送给模型的上下文长什么样”,而不是“界面上显示了什么”。
28
29
### 源码锚点
30
31
- `commands/context/context.tsx:18-18`
32
- `utils/messages.ts:4608-4643`
33
- `utils/analyzeContext.ts:320-320`
34
- `utils/analyzeContext.ts:918-964`
35
36
## 4. `/context` 里的 memory 统计来源
37
38
`analyzeContextUsage()` 会重新调用 `getSystemContext()` 和 `getMemoryFiles()`,再把 `memoryFiles` 单独拆成 token 统计项。也就是说,`/context` 里的 memory 视图来自重新计算,不是从 UI 层臆断或复述。
39
40
### 源码锚点
41
42
- `utils/analyzeContext.ts:272-320`
43
- `utils/analyzeContext.ts:918-964`
44
claude code/03-memory实现.md
`claude code`:memory 实现
1
# `claude code`:memory 实现
2
3
## 1. 跨会话文件型 memory:`memdir` + `claudemd`
4
5
长期 memory 的目录解析集中在 `memdir/paths.ts`。默认路径基于 `~/.claude/projects/<sanitized-git-root>/memory/`,并支持环境变量覆盖。`getAutoMemEntrypoint()` 指向 `MEMORY.md`,`getAutoMemDailyLogPath()` 指向按日期分层的 daily log。
6
7
`memdir/memdir.ts` 决定这些文件怎样进入 prompt:既可以读 `MEMORY.md`,也可以切换到 append-only daily log,还能组合 team memory。
8
9
### 源码锚点
10
11
- `memdir/paths.ts:223-257`
12
- `memdir/teamMemPaths.ts:73-73`
13
- `memdir/memdir.ts:199-419`
14
15
## 2. 哪些文件会被当成 memory
16
17
真正负责收集 memory 文件的是 `utils/claudemd.ts`。它按 `Managed -> User -> Project -> Local -> AutoMem -> TeamMem` 的顺序收集,支持 `@include`、frontmatter `paths`、去重和外部 include 约束。
18
19
`filterInjectedMemoryFiles()` 还会在特定实验开关下,把 `AutoMem` 或 `TeamMem` 从“注入到系统 prompt 的集合”中剔除。这说明“文件存在”与“本轮被注入”是两个不同概念。
20
21
### 源码锚点
22
23
- `utils/claudemd.ts:229-790`
24
- `utils/claudemd.ts:1142-1153`
25
26
## 3. 单会话摘要 memory:`SessionMemory`
27
28
`SessionMemory` 是独立的第二条 memory 路径。它把当前 session 的结构化摘要写到 `{projectDir}/{sessionId}/session-memory/summary.md`,由后台抽取器在 token / 工具调用阈值满足时更新,也支持手动触发。
29
30
它不是跨会话长期记忆,而是当前 session 的结构化摘要视图。
31
32
### 源码锚点
33
34
- `utils/permissions/filesystem.ts:261-261`
35
- `services/SessionMemory/sessionMemory.ts:272-387`
36
37
## 4. `summary.md` 的模板与约束
38
39
`services/SessionMemory/prompts.ts` 为 `summary.md` 定义了固定模板、更新 prompt、超长 section 警告和 compact 时的截断逻辑。这里的输出是带结构的摘要,不是自由文本日志。
40
41
### 源码锚点
42
43
- `services/SessionMemory/prompts.ts:86-256`
44
- `services/compact/sessionMemoryCompact.ts:1-1`
45
claude code/04-存储与状态.md
`claude code`:存储与状态
1
# `claude code`:存储与状态
2
3
## 1. 运行时状态
4
5
`bootstrap/state.ts` 里可以看到这套 runtime 关心的核心状态:原始工作目录、project root、session project dir、session 是否禁用持久化等。这些状态决定后续 transcript 和 session-memory 应该落到哪里。
6
7
### 源码锚点
8
9
- `bootstrap/state.ts:46-46`
10
11
## 2. 会话 transcript 的落盘
12
13
`utils/sessionStorage.ts` 负责 session transcript 的持久化路径,按 `{projectDir}/{sessionId}.jsonl` 一类布局保存,同时还管理 subagents 目录。它属于历史/会话存储,不直接等于 memory。
14
15
### 源码锚点
16
17
- `utils/sessionStorage.ts:202-202`
18
19
## 3. `session-memory` 路径与权限 carve-out
20
21
`utils/permissions/filesystem.ts` 专门为 `session-memory/summary.md` 留了读权限 carve-out。这反过来说明 `SessionMemory` 不是普通 UI 文件,而是 runtime 明确认识的一类内部路径。
22
23
### 源码锚点
24
25
- `utils/permissions/filesystem.ts:259-261`
26
27
## 4. 历史相关存储
28
29
- `history.ts` 维护命令历史文件。
30
- `assistant/sessionHistory.ts` 负责远端 session event 历史分页。
31
32
二者都属于 `history` / event 视角,不应与 `memdir` 或 `SessionMemory` 混淆。
33
34
### 源码锚点
35
36
- `history.ts:114-114`
37
- `assistant/sessionHistory.ts:1-1`
38
claude code/05-调用链、压缩与边界.md
`claude code`:调用链、压缩与边界
1
# `claude code`:调用链、压缩与边界
2
3
## 1. `/compact` 的主调用链
4
5
`/compact` 会先尝试 `SessionMemory` compaction,再走 `microcompact` / 传统压缩路径。执行成功后,它会清 `getUserContext()` 缓存、标记 post-compaction,并压掉相应警告。
6
7
这意味着压缩不仅改变消息窗口,也会直接影响后续 context 的重建方式。
8
9
### 源码锚点
10
11
- `commands/compact/compact.ts:46-117`
12
- `services/compact/sessionMemoryCompact.ts:1-1`
13
14
## 2. compact boundary 的意义
15
16
`/context` 和 API 视图都依赖 compact boundary。被 boundary 之前的消息不会继续作为“当前 prompt 历史”参与可视上下文分析,因此 compact 本质上会重写“哪些消息还属于当前可见上下文”。
17
18
### 源码锚点
19
20
- `utils/messages.ts:4608-4643`
21
- `commands/context/context.tsx:18-18`
22
23
## 3. 关键边界
24
25
- `history.ts` 是命令历史,不是语义记忆。
26
- `memdir` 是跨会话 memory。
27
- `SessionMemory` 是单会话摘要。
28
- `/context` 是 API 视图,不是 UI 原始视图。
29
30
阅读源码时如果不先把这四条边界分开,最容易把不同层面的“记忆”误合并。
31
32
### 源码锚点
33
34
- `history.ts:114-114`
35
- `memdir/memdir.ts:199-419`
36
- `services/SessionMemory/sessionMemory.ts:272-387`
37
- `utils/analyzeContext.ts:918-964`
38