开发工具Agent TracesAI 应用【免费下载链接】cli Entire CLI hooks into your Git workflow to capture AI agent sessions as you work. Sessions are indexed alongside commits, creating a searchable record of how code was written in your repo.项目地址https://gitcode.com/gh_mirrors/cli411/cli点击查看免费下载Entire CLI 通过 Git 钩子把 AI 编码会话Claude Code、Codex、Antigravity、OpenCode、Cursor 等以1:1 的 checkpoint形式随每次提交沉淀下来形成与代码提交一一对应、可检索的会话记录。本文以官方架构文档 checkpoint-scenarios.md 为骨架结合仓库源码逐场景讲解从「提示词 → 改动 → 提交」到「Agent 中途多次提交」「git add -p部分暂存」「git-refs 后端推送」等真实工作流下 checkpoint 的创建、链接与结转carry-forward机制读完即可理解 Entire 何时、如何、以及为什么这样生成每个 checkpoint。1. 核心机制一览在展开场景之前先建立三个基础概念对应源码中的SessionState与CheckpointSummary详见 sessions-and-checkpoints.md会话状态Session state每个回合结束时记录FilesTouched会话期间修改过的文件跨提示词累积与TouchedFileHashes每个文件在 Agent 离开时的 Git blob 哈希。在用户提交之前不写入任何 Git 对象——未提交的工作只存在于会话状态和本地 transcript 副本中。1:1 checkpoint每一次提交获得一个唯一的 checkpoint ID与提交通过Entire-Checkpointtrailer 双向关联。基于名称的链接 内容感知的结转只要提交携带了会话触碰过的任意路径就链接该会话记录的哈希只用于判断还剩多少工作要结转不用于决定是否链接。这三条规则在源码中对应两套完全分离的判定函数见 strategy/content_overlap.go判定函数比较方式目的重叠检测是否链接filesOverlapWithContentPostCommit、stagedFilesOverlapWithContentPrepareCommitMsg只按名称不比较内容让每个携带会话工作的提交都链接包括用户改过的文件结转检测还剩多少工作filesWithRemainingAgentChanges比较提交 blob 哈希与记录的回合末哈希支持把单个文件内的改动拆分到多个提交注意用户编辑 Agent 创建的文件远比整体覆盖常见因此链接只按名称判定修改、删除、新增皆可。唯一例外是会话记录为已删除的路径如果被提交作为新文件加入说明是别人重新创建的不链接。2. 会话状态机IDLE / ACTIVE / ENDEDcheckpoint 的创建时机由会话状态机驱动事件包括SessionStart、TurnStartUserPromptSubmit、TurnEndStop hook、GitCommitPostCommit hook、SessionStop以及CompactionPreCompress该状态机不是文档里的纸面设计而是直接由代码生成并强制执行的session.Transition(current, event, ctx)是一个无副作用的纯函数见 session/phase.go它返回下一个阶段和需要执行的动作ActionCondense、ActionCondenseIfFilesTouched、ActionDiscardIfNoFiles等再由ApplyTransition统一执行副作用。MermaidDiagram()函数甚至能从这张转移表自动生成上面的 Mermaid 图保证文档与实现永不脱节。几个关键分支值得注意IDLE GitCommit→ 直接Condense场景 1、4、5 的正常路径ACTIVE GitCommit→ 保持 ACTIVE 且Condense场景 2、3 的 Agent 中途提交路径ENDED GitCommit→ 有触碰文件则CondenseIfFilesTouched无则DiscardIfNoFilesrebase 进行中.git/rebase-merge/或.git/rebase-apply/存在时GitCommit 不会触发冷凝避免在变基中间态写入 checkpoint。3. 场景 1提示词 → 改动 → 提示词结束 → 用户提交最简单的工作流用户发提示词Agent 改文件提示词结束之后用户手动提交。关键点在回合结束TurnEnd时pending 工作只存在于会话状态和本地 transcript 副本.entire/metadata/session-id/full.jsonl与prompt.txt均为 git-ignored任何内容都不会在此时写入 GitPrepareCommitMsg钩子向提交信息追加Entire-Checkpoint: idtrailer用户可自行移除PostCommit钩子把会话冷凝到永久存储默认后端是entire/checkpoints/v1分支然后清理FilesTouched与哈希。SaveStep的记录细节见 strategy/touched_file_hashes.go每个修改或新增的常规文件用git hash-object计算 blob 哈希clean filter 与git add一致删除的路径记录为标记符号链接从不哈希git hash-object会跟随链接而非哈希目标路径字符串无哈希的路径一律回退到名称匹配。4. 场景 2Agent 在单个回合内提交用户指示 Agent「改完就提交」提交发生在 ACTIVE 阶段。关键点Agent 提交通过「无 TTY」识别tryAgentCommitFastPathmanual_commit_hooks.go在无 TTYAgent 子进程、CI或设置了commit_linkingalways时跳过内容检测直接为 ACTIVE 会话加 trailer延迟最终化Deferred finalizationPostCommit 先把「临时 transcript」commit 时刻已有的内容写入 checkpointHandleTurnEndStop hook再用完整 transcript 覆盖——因为 Agent 在提交后还会继续写后续内容工具结果、token 计数、task_completeTurnCheckpointIDs记录本回合内产生的所有 checkpoint ID供 Stop 时统一最终化。代码中HandleTurnEnd的逻辑manual_commit_hooks.go如果TurnCheckpointIDs非空就调用finalizeAllTurnCheckpoints用完整 transcript 替换每个 checkpoint 的临时内容若本回合无 carry-forwardFilesTouched为空还会把CheckpointTranscriptStart推进到 transcript 末尾避免下一个 checkpoint 重复收录已冷凝的内容。最终化是best-effort失败只记日志不失败 hook因为临时 transcript 已持久化checkpoint 不会丢失只是缺少完整上下文。5. 场景 3Agent 产生多个粒度提交用户指示「用粒度提交实现功能」一个回合内产生多次提交。关键点每个提交都有自己唯一的 checkpoint ID严格的 1:1 模型所有 checkpoint 在回合结束时一起最终化finalizeAllTurnCheckpoints循环处理TurnCheckpointIDs每个 checkpoint 都包含完整的会话 transcript作为上下文自包含设计。这也解释了「每个 checkpoint 的 transcript 有重叠」这一代价见下文 Known Caveats 第 1 条checkpoint 1 存 transcript 行 1-100checkpoint 2 存行 1-200checkpoint 3 存行 1-300。换取的是任意一个 checkpoint 都能独立还原整个会话对中途丢失、回退或 rebase 丢弃具备鲁棒性。6. 场景 4用户把改动拆成多次提交提示词结束后用户决定把 Agent 的改动拆成多个提交。关键点结转逻辑Carry-forward未提交的文件保留在会话状态中StepCount 1transcript 偏移重置为 0使下一次提交仍能链接到该会话每个提交各自获得唯一 checkpoint ID1:1 模型两个 checkpoint 都链接到同一个会话 transcript。内容感知的结转规则结转不是简单「没提交就留下」而是逐条规则判定实现于 strategy/content_overlap.go 的remainingClassifier与 strategy/touched_file_hashes.go文件不在提交中→ 还有剩余改动结转文件在提交中且提交 blob 哈希 记录的回合末哈希→ 已完整提交不结转文件在提交中哈希与记录不同但 clean-filter 后的工作树哈希 提交哈希→ 用户替换了 Agent 内容并完整提交不结转文件在提交中哈希与记录值和 clean-filter 工作树都不同→ 部分提交如git add -p结转提交删除了文件→ 若工作树也没有则丢弃无论有无记录哈希若工作树仍有重新创建或git rm --cached则保留记录的删除→ 只要仍 pending提交树仍有该路径、工作树没有即使提交修改了该路径就结转让最终删除它的提交链接一旦某提交移除了路径或文件被重新创建则丢弃无记录哈希旧版 CLI 会话、哈希失败、符号链接、经任务记录或 per-tool hook 加入的路径→ 已提交时只要工作树与提交 blob 不同就保留、相同则丢弃未提交时除非同时不在提交和工作树提交仍有但工作树没有的路径是 pending 删除否则保留Agent 创建后又删除的未跟踪文件工作树和 HEAD 都没有、无 staged blobgit status 不报告删除→ 下一次回合末记录为删除并丢弃结转使之后用户在该路径新建的文件不会按名称误链接。blob 仍被 staged 为新文件的路径除外用户已git add下一次提交会加入该 staged blob 并保持哈希使该提交链接会话。同样的规则适用于此类文件以删除形式到达回合末git status 报告为ADHEAD 中没有、blob 仍 staged 的删除不记录为删除HEAD 中路径的删除git rm或删除已提交文件则记录。提交后的结转遵循相同规则工作树和提交都缺失的哈希路径仅当没有 staged blob 时才丢弃因此用户留在部分提交之外的 staged 文件会保持 pending直到添加它的提交出现。权衡回合之间用git stash -u或手工移出工作树的文件看起来一样恢复后只有 Agent 再次触碰才会重新链接。git add -N的 intent-to-add 条目不含 blob、永不提交不计为 staged。记录的哈希由原生 Gitgit hash-object计算因此 Git LFS、ident、自定义 clean filter不会产生幻影差异。但git hash-object不应用git add的索引感知行尾规则已以 CRLF 提交的文件不会被textauto或core.autocrlf归一化所以记录哈希可能与提交 blob 不同。因此记录哈希只是快速路径提交 blob 记录哈希 完全提交和删除标记两者不同时是否「工作树仍与提交不同」交给git statuspathspec 限定、--no-optional-locks应用与git add相同的规则回答status 未报告的路径视为完成报告的路径保留status 失败则保留。符号链接在回合末从不哈希git hash-object跟随链接回退到名称匹配。7. 场景 5用git add -p部分暂存用户用交互式暂存只提交一个文件的某些 hunk其余 Agent 改动保持未提交。这使单个文件内的改动也能跨多个提交拆分。关键点内容感知结转比较的是 Git blob 哈希不只是文件名单个文件内的部分暂存git add -p能被准确识别每个提交都链接会话——即使只拆分了单个文件的改动。内容比较的工作流程注意源码中的实现细节第 4 步「工作树哈希 vs 提交哈希」的最终裁决由git status完成而非再次git hash-object——因为 status 应用索引感知的行尾规则而 hash-object 不应用直接比哈希会把每个 CRLF 文件永远判为 dirty见 content_overlap.go 中filesWithRemainingAgentChanges的注释。status 失败时所有候选路径都保留绝不靠猜测丢弃。8. 如何把提交链接到会话一个提交只要携带FilesTouched中的任意路径按名称匹配就链接会话修改、删除、新增文件皆可无论提交内容是什么。用户编辑 Agent 创建的文件远比整体覆盖常见所以链接不比较提交 blob 与记录哈希。唯一例外会话记录为已删除的路径若提交把它作为新文件加入说明是别人在 Agent 删除后重新创建的不链接。示例用户重写 Agent 创建的文件链接检查的实现位于 strategy/content_overlap.gofilesOverlapWithContentPostCommit基于已提交的 HEAD 树与stagedFilesOverlapWithContentPrepareCommitMsg基于暂存区与 HEAD 树都先查「修改」再查「新增」只有「会话记录为删除的新文件」通过newFileIsSessionWork被排除。这与会话状态的记录方式吻合回合末SaveStepFilesTouched累积修改/新增/删除路径TouchedFileHashes记录常规文件的 blob 哈希、删除路径记录touched_file_hashes.go 中applyTouchedFileHashes。9. 场景 6git-refs 后端——冷凝与推送以上所有场景描述的是默认git-branch后端冷凝到单一的entire/checkpoints/v1分支。当主后端为git-refs时会话/时机/重叠逻辑完全相同——唯一区别是冷凝写到哪里、结果如何推送。checkpoint 何时创建、包含什么、内容感知结转如何工作一律不变。两个差异冷凝目标不再把 checkpoint 子树拼接到v1分支的id[:2]/id[2:]/下git-refs 把同一子树作为每个 checkpoint 专属 ref的树根提交到refs/entire/checkpoints/shard/id首次写入为孤儿提交后续 backfill 有父提交。ref 被记录到推送发现队列push-discovery queue而不是推进共享分支尖端。推送机制pre-push 排空队列并只推送发生变化的 refs仅 fast-forward而不是推送一个分支。关键点冷凝为每个 checkpoint 写一个提交到refs/entire/checkpoints/shard/id没有需要串行化的共享分支尖端入队是best-effort本地落盘成功但入队失败的 checkpoint本地仍然正确并在下次写入时重新入队推送从不强制force分歧的 ref 通过 fetch replay 恢复保证远端提交作为祖先保留strategy/manual_commit_push.go 的PrePush分支、strategy/push_common.go的pushCheckpointRefWithRecovery失败或中断的推送让 refs 留在队列中等待下一次 pre-push——队列只会退化为「将重试」绝不会静默丢失读取按 ID 类型跨两个后端路由因此迁移中的仓库能透明地同时读取 hexbranch与 ULIDrefscheckpoint。实现细节推送队列是 git common dir 下的 flock 保护 JSONL 文件entire-checkpoint-push-queue.jsonlcheckpoint/pushqueue.go所有共享对象库的 worktree 共用一条队列排空时去重但先不移除只有在确认推送成功后才删除对应 refs期间新追加的条目保留因此失败必然重试。shard 取 ID 的最后两个字符id.ShardFor()见 checkpoint/refs_naming.goULID 头部字符编码毫秒时间戳相近 checkpoint 几乎不变、尾部随机按后缀分片既均匀又保持 ID 可时间排序。完整后端设计分片、读取路由、配置、回滚见 ref-checkpoint-backend.md。10. 场景汇总表场景Checkpoint 创建时机Checkpoint 内容关键机制1. 提示词后用户提交PostCommit (IDLE)完整 transcript正常冷凝2. Agent 回合内提交PostCommit (ACTIVE) HandleTurnEnd完整 transcriptStop 时最终化延迟最终化3. Agent 多次提交每次 PostCommit (ACTIVE) HandleTurnEnd每个 checkpoint 完整 transcriptTurnCheckpointIDs 追踪4. 用户拆分提交每次 PostCommit (IDLE)每个 checkpoint 完整 transcript内容感知结转5.git add -p部分暂存每次 PostCommit (IDLE)每个 checkpoint 完整 transcript内容感知结转哈希比较6. git-refs 后端与 1–5 相同后端正交与 1–5 相同冷凝到refs/entire/checkpoints/shard/id pre-push 排空推送队列11. 已知的注意事项Known Caveats11.1 跨提交的冗余 transcript 数据每个 checkpoint 存储截至该点的完整会话 transcript。一个会话产生多个提交场景 3、4、5时各 checkpoint 的 transcript 相互重叠。示例3 次提交的会话Checkpoint 1transcript 行 1-100Checkpoint 2transcript 行 1-200再次包含 1-100Checkpoint 3transcript 行 1-300再次包含 1-200权衡换取的是 checkpoint 检索的简单性每个自包含代价是存储效率。11.2 Token 用量求和具有误导性每个 checkpoint 的metadata.json中的 token 用量是截至该点的会话累计值。对同一会话的多个 checkpoint 求和会重复计数。示例Checkpoint 110,000 tokens当时会话总量Checkpoint 225,000 tokens当时会话总量朴素求和35,000 tokens ❌实际用量25,000 tokens ✓正确做法取会话最后一个 checkpoint的 token 数或单独追踪增量 delta。11.3 没有按文件的提示词归因Checkpoint 不显式标注哪个提示词创建了哪个文件。要确定这一点必须解析 transcript把tool_use条目与之前的user消息关联起来。metadata 中的files_touched列表跨所有提示词累积。11.4 结转的 checkpoint 包含完整 transcript结转发生时场景 4CheckpointTranscriptStart重置为 0。这意味着每个结转 checkpoint 都包含整个 transcript而不仅是上次 checkpoint 之后的新内容。代码注释明确说明了这一取舍manual_commit_hooks.go 的carryForwardRemainingFilesCheckpointTranscriptStart 0是有意为之保证每个 checkpoint 独立可读StepCount 1让会话保持 pending并通过 stored-transcript 检查路由sessionHasNewContent。影响对于很多部分提交的长会话checkpoint 存储随「会话长度 × 提交次数」线性增长。11.5 HandleTurnEnd 前崩溃会留下临时 transcript场景 2、3Agent 回合内提交中checkpoint 在 PostCommit 期间以「临时」transcript 保存完整 transcript 在 HandleTurnEndStop hook写入。如果会话在 Stop hook 触发前崩溃或被杀死checkpoint 存在但只含部分 transcript会话状态中的TurnCheckpointIDs记录哪些需要最终化下次会话启动不会自动最终化孤儿 checkpoint。11.6 两种不同的检查系统使用两个目的不同的检查只有第二个比较内容A. 重叠检测filesOverlapWithContent、stagedFilesOverlapWithContent——判断提交是否应链接会话修改、删除、新增文件一律按名称匹配不做内容比较例外会话记录为删除的路径被提交为新文件时不链接用于非 ACTIVE 会话的 PrepareCommitMsg/PostCommit目的让每个携带会话工作的提交都链接包括用户编辑过的。B. 结转检测filesWithRemainingAgentChanges——判断哪些文件需要结转应用于所有已提交文件比较提交内容哈希与记录的回合末哈希哈希不匹配且工作树仍不同 部分提交文件结转目的支持单文件内改动跨提交拆分场景 5。11.7 结转内容被新提示词取代文件结转后又被新提示词修改新提示词的回合末为该文件记录新的哈希结转的哈希被覆盖之后的提交与新提示词的内容比较而非原始结转内容。示例提示词 1Agent 给文件 A 写入 100 行用户git add -p提交 50 行结转A 留在FilesTouched哈希为 100 行版本提示词 2Agent 给 A 再加 50 行工作树共 150 行回合末A 的记录哈希更新为 150 行版本用户提交与 150 行比较而非原始 100 行这是正确行为——记录哈希反映会话工作的当前合并状态。11.8 常规操作中的自动清理大部分孤儿数据会自动清理会话状态无 pending 工作State.HasPendingWork且无LastCheckpointID的已结束会话在会话列举时移除遗留 shadow 分支旧版 CLI 写入的entire/hex-hex分支不会自动删除entire doctor会报告它们entire doctor --force删除而不触碰会话状态。漏网之鱼可手动运行entire clean --allentire clean --all # 预览孤儿条目包括遗留 shadow 分支 entire clean --all --force # 删除孤儿条目这些命令的语义在 sessions-and-checkpoints.md 中有更完整的说明entire doctor只报告/清理 checkpoint 数据entire clean还会清掉基于 HEAD 的会话状态因此会丢弃其 pending 工作仅形如entire/hex的裸分支只由entire clean --all需确认或卸载移除。checkpoint 的 ID 格式、目录分片与双向查找细节同样见 sessions-and-checkpoints.md 的「Checkpoint ID Linking」一节冷凝实现的契约见 checkpoint-implementation.md。12. 小结从六个场景可以看出 Entire CLI 的 checkpoint 设计哲学时机由会话状态机决定链接只看名称结转只看内容哈希。回合结束从不写 Git 对象pending 工作留在会话状态与本地 transcript提交时才冷凝成永久记录1:1 模型让每个提交都有独立、自包含、可检索的会话快照而内容感知结转让「用户拆分提交」「git add -p部分暂存」等现实工作流也能被准确追踪——这正是 Entire 能把 AI 编码过程变成可搜索仓库档案的核心能力。赞分享开发工具Agent TracesAI 应用【免费下载链接】cli Entire CLI hooks into your Git workflow to capture AI agent sessions as you work. Sessions are indexed alongside commits, creating a searchable record of how code was written in your repo.项目地址https://gitcode.com/gh_mirrors/cli411/cli点击查看免费下载相关推荐如何快速构建AMD黑苹果EFIOpCore-Simplify自动化配置终极指南如何快速构建AMD黑苹果EFIOpCore Simplify自动化配置终极指南 想要在AMD平台上轻松部署macOS系统OpCore Simplify作为一开发工具CLIChaldeaFGO玩家的智能指挥官从混乱到有序的游戏体验革命ChaldeaFGO玩家的智能指挥官从混乱到有序的游戏体验革命 在《Fate/Grand Order》这款深受全球玩家喜爱的角色扮演游戏中御主们常常面临一桌面应用移动开发Wren AI自然语言转 SQL零代码数据库查询不用排队等开发Wren AI自然语言转 SQL零代码数据库查询不用排队等开发 业务同事想查个销售额排行自己不会写 SQL只能找开发排队提需求。Wren AI 是一个开后端人工智能AI Agent数据分析上一篇如何在Kubernetes上构建终极GPU共享平台HAMi完整指南下一篇Meteor iOS 安全最佳实践数据加密、认证与权限控制终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考