图 2:Hook 生命周期 - 从 SessionStart 到 SessionEnd 的完整流程 会话开始阶段 SessionStart → 会话开始或恢复 InstructionsLoaded → TaskCompleted → 任务标记完成 ConfigChange → 配置文件变更 WorktreeCreate → 创建工作树 WorktreeRemove → 移除工作树 PreCompact → 上下文压缩前 SessionEnd :会话结束时清理资源 关键洞察: 会话级事件:SessionStart、SessionEnd 每个会话只触发一次 循环事件:在代理循环中,某些事件会反复触发(PreToolUse、PostToolUse 种 Hook 事件,按生命周期阶段分类: 会话管理(4 种) 事件 触发时机 可阻止 匹配器支持 典型用途 SessionStart 会话开始或恢复 ❌ ✅ 加载上下文、设置环境变量、显示项目状态 SessionEnd 16 种 Hook 事件覆盖了 Claude Code 的完整生命周期: 会话管理:SessionStart、SessionEnd、InstructionsLoaded、ConfigChange 用户交互
PreToolUse → 拦截危险部署、门控审查 agent PostToolUse → 编辑时路由上下文、检测循环 Stop → 验证完成候选品(transcript × git diff) SessionEnd PreToolUse → 每次工具调用之前 PostToolUse → 每次工具调用之后 PreCompact → 上下文压缩之前 Stop → agent 尝试停止时 SessionEnd 038 的记录,Claude Code 源码中有 28 种 hook 事件: Claude Code 原生 Hook 事件 会话生命周期 SessionStart ← 会话开始时触发 SessionEnd 每 50 次调用注入 Objective Recitation precompact.sh 压缩丢失关键信息 压缩前注入不可降级规则 + 原始目标 session-reflection 经验无法积累 SessionEnd AI 编程工具 依赖项 具体机制 wow-harness 怎么用的 7 阶段 Hook 协议 SessionStart/PreToolUse/PostToolUse/PreCompact/Stop/SessionEnd
session_timer.py"start2>/dev/null||true-Stop→python"$HOME/.claude/hooks/session_timer.py"stop2>/dev/null||true-SessionEnd
save-hook.ts # PostToolUse │ │ ├── summary-hook.ts # Stop │ │ ├── cleanup-hook.ts # SessionEnd
PreToolUse工具执行前拦截危险命令、修改参数PostToolUse工具执行后自动格式化、通知NotificationClaude等待输入时桌面通知SessionStart会话开始时加载环境变量SessionEnd
→ 每次工具调用之前 PostToolUse → 每次工具调用之后 PreCompact → 上下文压缩之前 Stop → agent 尝试停止时 SessionEnd
这个插件会挂钩到Claude Code的生命周期——SessionStart初始化记忆,PostToolUse捕获动作,UserPromptSubmit注入相关上下文,PreCompact在上下文重置前保留记忆,SessionEnd
• UserPromptSubmit:用户提交指令时,记录问题和上下文 • PostToolUse:工具执行后,捕获Read/Write/Edit等操作 • Stop:任务暂停时,保存中间状态 • SessionEnd
SessionEnd(会话结束) 触发时机:Claude Code会话完全结束时 执行内容:标记会话为已完成,确保所有数据持久化 双数据库存储系统 claude-mem使用两个数据库来存储记忆: SQLite
系统里有几个角色各自分工: 5 个生命周期钩子 SessionStart、UserPromptSubmit、PostToolUse、Stop、SessionEnd,全程自动触发,不用你手动喊 一个常驻
的平均值替换它 将柱子添加到内部栈以供下一个过滤器或策略立即处理(回放过滤器将接管) 分解柱子第二部分的解剖: 复制传入数据柱 将 OHL 价格替换为Close价格 将时间更改为日期 + sessionend data.OpenInterest] = oi # Adjust times dt = datetime.datetime.combine(datadt, data.p.sessionend ohlbar[data.DateTime] = data.date2num(dt) dt = datetime.datetime.combine(datadt, data.p.sessionend data.OpenInterest] = oi # Adjust times dt = datetime.datetime.combine(datadt, data.p.sessionend
UserPromptSubmit → PreToolUse → [PermissionRequest] → Tool Execution → PostToolUse/PostToolUseFailure → Stop → SessionEnd
times and - removed) ''' if data.sessionstart <= data.datetime.tm(0) <= data.sessionend compression=1, sessionstart=dtstart, # internally just the "time" part will be used sessionend Reset sessionend to MAXDATE & fall through - If session end is flagged as MAXDATE data.datetime.tm2datetime(data.sessionstart) self.sessend = sessend = data.datetime.tm2datetime(data.sessionend
主 Agent 准备停止时 检查是否跑了测试/build SubagentStop 子 Agent 准备停止时 验证子任务完成度 SessionStart 会话开始时 加载环境变量、设置项目上下文 SessionEnd
主 Agent 准备停止时 检查是否跑了测试/build SubagentStop 子 Agent 准备停止时 验证子任务完成度 SessionStart 会话开始时 加载环境变量、设置项目上下文 SessionEnd
('name', ''), ('compression', 1), ('timeframe', TimeFrame.Days), ('sessionend 如果传递了sessionend(一个 datetime.time 对象),它将被添加到数据源的datetime行中,从而可以识别会话结束的时间 示例二进制数据源 backtrader已经为VisualChart
IBStore.getdata(*args, **kwargs) 在这种情况下,许多**kwargs与数据源相同,如dataname、fromdate、todate、sessionstart、sessionend OandaStore.getedata(\*args, **kwargs) 在这种情况下,许多**kwargs与数据提要(例如dataname、fromdate、todate、sessionstart、sessionend
VCStore.getedata(*args, **kwargs) 在这种情况下,许多**kwargs对于数据源都是常见的,如dataname,fromdate,todate,sessionstart,sessionend timeframe=bt.TimeFrame.Days, compression=1, sessionstart=datetime.time(9, 0), sessionend timeframe=bt.TimeFrame.Minutes, compression=5, sessionstart=datetime.time(9, 0), sessionend
文件变化时否触发构建、刷新缓存WorktreeCreate创建 Git worktree 时是初始化环境PreCompact上下文压缩前是保存关键状态PostCompact上下文压缩后否恢复关键上下文SessionEnd
timeframe=bt.TimeFrame.Days, compression=1, sessionstart=datetime.time(9, 0), sessionend timeframe=bt.TimeFrame.Minutes, compression=5, sessionstart=datetime.time(9, 0), sessionend