本章概述
系列目录:Claude Code 源码分析系列索引
State 管理是 Claude Code 的核心基础设施,负责会话状态、应用配置、任务数据的存储和持久化。
你将学到
- ✅ 状态管理架构设计
- ✅ 会话存储与恢复
- ✅ 任务状态管理
- ✅ 设置持久化
- ✅ 数据备份策略
状态管理概览
flowchart TB
subgraph StateTypes["状态类型"]
A[AppState] --> B[会话状态]
A --> C[工具权限]
A --> D[UI 状态]
E[持久化状态] --> F[会话存储]
E --> G[设置配置]
E --> H[任务列表]
end
subgraph Storage["存储层"]
I[内存] --> J[磁盘 JSON]
J --> K[Git Worktree]
end
subgraph Sync["同步机制"]
L[自动保存] --> M[定期备份]
N[事件触发] --> O[变化监听]
end
核心文件结构
src/
├── state/ # 状态管理
│ ├── AppState.tsx # 应用状态 Provider
│ ├── AppStateStore.ts # Store 定义
│ └── store.ts # Store 实现
├── utils/sessionStorage.ts # 会话存储
├── utils/settings/ # 设置管理
│ ├── settings.ts
│ └── settingsCache.ts
└── utils/tasks.ts # 任务状态
应用状态(AppState)
状态定义
// state/AppStateStore.ts
export type AppState = {
// 会话状态
messages: Message[]
sessionId: string
isLoading: boolean
// 工具权限上下文
toolPermissionContext: ToolPermissionContext
// UI 状态
theme: ThemeName
spinnerMode: SpinnerMode
// 上下文信息
context: ContextInfo
// 成本追踪
costTracker: CostTrackerState
}
export function getDefaultAppState(): AppState {
return {
messages: [],
sessionId: generateSessionId(),
isLoading: false,
toolPermissionContext: getDefaultToolPermissionContext(),
theme: 'default',
spinnerMode: 'normal',
context: getDefaultContext(),
costTracker: getDefaultCostTracker()
};
}
Store 实现
// state/store.ts
export type AppStateStore = {
getState: () => AppState
setState: (updater: (prev: AppState) => AppState) => void
subscribe: (listener: () => void) => () => void
}
export function createStore(
initialState: AppState,
onChange?: OnChangeCallback
): AppStateStore {
let state = initialState;
const listeners = new Set<() => void>();
return {
getState: () => state,
setState: (updater) => {
const newState = updater(state);
const oldState = state;
state = newState;
// 通知所有监听器
listeners.forEach(listener => listener());
// 触发变化回调
onChange?.({ newState, oldState });
},
subscribe: (listener) => {
listeners.add(listener);
return () => listeners.delete(listener);
}
};
}
React 集成
// state/AppState.tsx
export const AppStoreContext = React.createContext<AppStateStore | null>(null);
export function AppStateProvider({ children, initialState }: Props) {
const [store] = useState(() =>
createStore(initialState ?? getDefaultAppState())
);
return (
<AppStoreContext.Provider value={store}>
{children}
</AppStoreContext.Provider>
);
}
export function useAppStore(): AppStateStore {
const store = useContext(AppStoreContext);
if (!store) {
throw new Error('useAppStore must be used within AppStateProvider');
}
return store;
}
export function useAppState<T>(selector: (state: AppState) => T): T {
const store = useAppStore();
const [value, setValue] = useState(() => selector(store.getState()));
useEffect(() => {
return store.subscribe(() => {
setValue(selector(store.getState()));
});
}, [store, selector]);
return value;
}
会话存储
会话数据结构
// utils/sessionStorage.ts
export type SessionData = {
sessionId: string
title?: string
messages: Message[]
createdAt: number
updatedAt: number
metadata?: SessionMetadata
}
export type SessionMetadata = {
workingDirectory: string
gitBranch?: string
gitCommit?: string
agentSettings?: AgentSettings
}
会话存储实现
// utils/sessionStorage.ts
const SESSIONS_DIR = path.join(CLAUDE_DIR, 'sessions');
export async function saveSession(session: SessionData): Promise<void> {
const sessionPath = getSessionPath(session.sessionId);
// 更新元数据
const data: SessionData = {
...session,
updatedAt: Date.now()
};
// 写入文件
await writeFile(
sessionPath,
JSON.stringify(data, null, 2)
);
// 更新索引
await updateSessionIndex(data);
}
export async function loadSession(
sessionId: string
): Promise<SessionData | null> {
const sessionPath = getSessionPath(sessionId);
try {
const content = await readFile(sessionPath, 'utf-8');
return JSON.parse(content);
} catch (error) {
if (isFileNotFoundError(error)) {
return null;
}
throw error;
}
}
export async function listSessions(): Promise<SessionSummary[]> {
const index = await loadSessionIndex();
return index.sessions
.sort((a, b) => b.updatedAt - a.updatedAt);
}
会话恢复
// utils/conversationRecovery.ts
export async function loadConversationForResume(
sessionId: string
): Promise<ResumeData | null> {
const session = await loadSession(sessionId);
if (!session) {
return null;
}
// 恢复应用状态
const appState = getDefaultAppState();
appState.messages = session.messages;
appState.sessionId = sessionId;
// 恢复上下文
if (session.metadata) {
await restoreContext(session.metadata);
}
return {
appState,
sessionId,
title: session.title
};
}
任务状态管理
任务定义
// utils/tasks.ts
export type Task = {
id: string
content: string
status: TaskStatus
owner?: AgentId
createdAt: number
updatedAt: number
metadata?: TaskMetadata
}
export type TaskStatus =
| 'pending'
| 'in_progress'
| 'completed'
| 'blocked'
| 'cancelled'
export type TaskList = {
id: string
tasks: Task[]
updatedAt: number
}
export const DEFAULT_TASKS_MODE_TASK_LIST_ID = 'default';
export const TASK_STATUSES = {
PENDING: 'pending',
IN_PROGRESS: 'in_progress',
COMPLETED: 'completed',
BLOCKED: 'blocked',
CANCELLED: 'cancelled'
} as const;
任务存储
// utils/tasks.ts
const TASKS_FILE = path.join(CLAUDE_DIR, 'tasks.json');
export async function loadTaskList(
listId: string = DEFAULT_TASKS_MODE_TASK_LIST_ID
): Promise<TaskList> {
try {
const content = await readFile(TASKS_FILE, 'utf-8');
const lists = JSON.parse(content);
return lists[listId] || createDefaultTaskList(listId);
} catch (error) {
return createDefaultTaskList(listId);
}
}
export async function saveTaskList(list: TaskList): Promise<void> {
const lists = await loadAllTaskLists();
lists[list.id] = {
...list,
updatedAt: Date.now()
};
await writeFile(TASKS_FILE, JSON.stringify(lists, null, 2));
}
任务更新
// tools/TodoWriteTool/TodoWriteTool.ts
export async function updateTasks(
listId: string,
updates: TaskUpdate[]
): Promise<void> {
const list = await loadTaskList(listId);
for (const update of updates) {
const index = list.tasks.findIndex(t => t.id === update.id);
if (index >= 0) {
// 更新现有任务
list.tasks[index] = {
...list.tasks[index],
...update,
updatedAt: Date.now()
};
} else {
// 创建新任务
list.tasks.push({
id: update.id,
content: update.content,
status: update.status || 'pending',
createdAt: Date.now(),
updatedAt: Date.now()
});
}
}
await saveTaskList(list);
}
设置管理
设置定义
// utils/settings/types.ts
export type Settings = {
// 编辑器设置
editor: {
theme: ThemeName
fontSize: number
tabSize: number
}
// 代理设置
agent: {
model: string
effort: EffortValue
permissionMode: PermissionMode
}
// MCP 设置
mcp: {
servers: Record<string, McpServerConfig>
enabled: boolean
}
// 插件设置
plugins: {
enabled: string[]
disabled: string[]
}
}
export type SettingSource =
| 'default'
| 'user'
| 'project'
| 'managed'
| 'cli'
设置层级
设置优先级(从高到低):
1. CLI 参数
2. 项目设置 (.claude/settings.json)
3. 用户设置 (~/.claude/settings.json)
4. 管理设置 (远程配置)
5. 默认设置
设置加载
// utils/settings/settings.ts
export async function getInitialSettings(): Promise<Settings> {
// 从各层级加载设置
const defaultSettings = getDefaultSettings();
const userSettings = await loadUserSettings();
const projectSettings = await loadProjectSettings();
const managedSettings = await loadManagedSettings();
// 合并设置(高优先级覆盖低优先级)
return mergeSettings(
defaultSettings,
userSettings,
projectSettings,
managedSettings
);
}
export async function loadUserSettings(): Promise<Partial<Settings>> {
const settingsPath = path.join(CLAUDE_HOME, 'settings.json');
try {
const content = await readFile(settingsPath, 'utf-8');
return JSON.parse(content);
} catch {
return {};
}
}
export async function loadProjectSettings(): Promise<Partial<Settings>> {
const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
try {
const content = await readFile(settingsPath, 'utf-8');
return JSON.parse(content);
} catch {
return {};
}
}
设置变更
// utils/settings/applySettingsChange.ts
export async function applySettingsChange(
source: SettingSource,
updater: (settings: Settings) => Settings
): Promise<void> {
// 获取当前设置
const current = await getSettings();
// 应用变更
const updated = updater(current);
// 验证设置
const validation = validateSettings(updated);
if (!validation.valid) {
throw new SettingsValidationError(validation.errors);
}
// 保存到对应层级
await saveSettings(source, updated);
// 触发变更事件
emitSettingsChange(source, current, updated);
}
数据备份策略
自动备份
// utils/backup.ts
const BACKUP_DIR = path.join(CLAUDE_DIR, 'backups');
const MAX_BACKUPS = 10;
export async function createBackup(): Promise<string> {
const timestamp = new Date().toISOString();
const backupPath = path.join(BACKUP_DIR, timestamp);
// 备份会话
await backupSessions(backupPath);
// 备份设置
await backupSettings(backupPath);
// 清理旧备份
await cleanupOldBackups();
return backupPath;
}
async function cleanupOldBackups(): Promise<void> {
const backups = await listBackups();
if (backups.length > MAX_BACKUPS) {
const toDelete = backups
.sort((a, b) => a.createdAt - b.createdAt)
.slice(0, backups.length - MAX_BACKUPS);
for (const backup of toDelete) {
await removeDirectory(backup.path);
}
}
}
会话归档
// utils/sessionStorage.ts
export async function archiveOldSessions(
maxAgeDays: number = 30
): Promise<number> {
const sessions = await listSessions();
const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
let archived = 0;
for (const session of sessions) {
if (session.updatedAt < cutoff) {
await archiveSession(session.sessionId);
archived++;
}
}
return archived;
}
最佳实践
1. 状态更新模式
// ✅ 使用函数式更新
store.setState(prev => ({
...prev,
messages: [...prev.messages, newMessage]
}));
// ❌ 避免直接修改
const state = store.getState();
state.messages.push(newMessage); // 错误!
2. 选择性订阅
// ✅ 只订阅需要的部分
const messages = useAppState(state => state.messages);
// ❌ 避免订阅整个状态
const state = useAppState(state => state); // 性能差
3. 错误处理
// ✅ 健壮的状态加载
try {
const session = await loadSession(sessionId);
if (!session) {
return createNewSession();
}
return session;
} catch (error) {
logError('Failed to load session', error);
return createNewSession();
}
小结
本章分析了 Claude Code 的 State 状态管理:
核心概念
| 概念 | 说明 | 应用场景 |
|---|---|---|
| Store | 状态容器 | 应用状态管理 |
| Session | 会话数据 | 对话持久化 |
| Tasks | 任务列表 | 任务追踪 |
| Settings | 设置配置 | 用户偏好 |
| Backup | 备份策略 | 数据安全 |
架构优势
- 集中管理 - Store 模式统一状态
- 类型安全 - TypeScript 保障
- 持久化 - 自动保存到磁盘
- 可恢复 - 会话恢复机制
学习收获
- 📦 状态管理 - Store 模式实践
- 💾 持久化 - 数据存储策略
- 🔄 状态同步 - 自动保存机制
- 🛡️ 数据安全 - 备份与恢复
系列导航:
- ← 上一篇:第6章:Services 业务逻辑层设计
- → 下一篇:第8章:Skills 技能系统实现原理
- 返回:系列索引