
【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载Context Window Monitor是 gsd-core 内置的一对生命周期钩子lifecycle hooksstatusline钩子把每次渲染时的上下文指标写入临时桥文件PostToolUse/AfterTool监控钩子随后读取该文件在剩余上下文跌破阈值时把警告以additionalContext形式注入 Agent 的对话流使 Agent 自身具备对上下文耗尽的感知能力。本指南以 docs/context-monitor.md 为骨架结合 hooks/gsd-context-monitor.js、hooks/gsd-statusline.js 与 tests/perf-317-context-monitor-fs.test.cjs 的源码实现完整讲解其工作原理、双阈值体系与调优方法、防抖与压缩compaction重置机制、安全降级设计以及如何把它与/gsd-pause-work状态保存工作流衔接帮助你在长会话中避免撞墙式上下文枯竭。问题背景状态栏能看见Agent 却看不见gsd-core 的 statusline 钩子会在每次渲染时把上下文使用率显示给用户模型名、GSD 状态、目录、带颜色的上下文进度条等。但用户能看到不代表Agent能看到——Agent 不会去读状态栏。结果就是当上下文所剩无几时Agent 毫不知情地继续工作直到真正撞上上下文上限——而此时可能正处在任务中途任何状态都没有保存。Context Window Monitor要解决的正是这个不对称把上下文余量信号从给用户看变成给 Agent 看。工作原理一条桥文件数据流监控机制是一个清晰的两段式数据流见 架构图statusline 钩子写指标每次状态栏渲染时hooks/gsd-statusline.js把上下文指标写入/tmp/claude-ctx-{session_id}.jsoncontext monitor 读指标每次工具调用结束后hooks/gsd-context-monitor.jsClaude Code 注册为PostToolUseAntigravity CLI 注册为AfterTool读取该桥文件跌破阈值注入警告当剩余上下文低于阈值时钩子把警告作为additionalContext注入对话Agent 收到并行动Agent 在对话流中看到警告文本从而调整自己的行为收尾当前任务、避免开启新复杂工作、立即保存状态。在部分宿主上该钩子还注册了其他生命周期事件如PreCompact见 #772。这些事件永远不会发出警告因为只有具备注入能力的事件才接受additionalContext信封PreCompact被特殊处理它只重置会话级状态见下文 防抖与 PreCompact 重置后立即返回不执行防抖计数与面包屑记账。桥文件格式桥文件是一个简单的 JSON 对象由 statusline 钩子在 hooks/gsd-statusline.js 中写入{ session_id: abc123, remaining_percentage: 28.5, used_pct: 71, timestamp: 1708200000 }其中remaining_percentage直接取宿主下发的context_window.remaining_percentage字段gsd-statusline.jsused_pct使用未经缓冲归一化的原始值Math.round(100 - remaining)以保证与宿主原生/context报告口径一致状态栏进度条用的归一化值会使警告消息虚高约 13 个百分点见 #2451。session_id在写入前会做路径穿越防护包含/、\或..的 session id 一律不写桥文件gsd-statusline.js防止恶意 session id 把文件写出临时目录。监控钩子的输入处理gsd-context-monitor.js从 stdin 读取 JSON 载荷提取session_id与事件名gsd-context-monitor.js。session_id缺失或含路径穿越序列时直接静默退出随后构造三个临时文件路径claude-ctx-{session_id}.json—— 指标桥文件claude-ctx-{session_id}-warned.json—— 警告哨兵防抖记账claude-ctx-{session_id}-compacted.json—— 压缩水印compaction watermark。双阈值体系WARNING 与 CRITICAL监控钩子定义了两个触发点fire-point均以剩余上下文百分比衡量默认值见 gsd-context-monitor.js级别剩余上下文Agent 行为Normal 35%不警告WARNING 35%收尾当前任务避免开启新的复杂工作CRITICAL 25%立即停止保存状态/gsd-pause-work实际注入的警告文案根据 GSD 是否激活工作目录是否存在.planning/STATE.md分两种变体GSD 激活时提示不要启动新复杂工作、不要写交接文件GSD 状态已记录在 STATE.md请告知用户以便在下一个自然停顿点运行/gsd:pause-workGSD 未激活时则提示告知用户上下文不足并询问如何继续未经用户要求不得自主保存状态或写交接文件gsd-context-monitor.js。警告刻意避免使用强制命令式措辞以免覆盖用户偏好#884。调优触发点.planning/config.json35 与 25 只是默认值不是固定值。剩余 35% 能买到多少跑道空间取决于窗口大小和当前阶段在做什么因此两个触发点都允许按项目在.planning/config.json中覆盖#4285{ hooks: { context_warnings: true, context_warning_threshold: 45, context_critical_threshold: 30 } }注意直接改gsd-context-monitor.js里的常量不会生效。该文件位于托管钩子注册表hooks/managed-hooks-registry.cjs 中登记了gsd-context-monitor.js下次安装会把 vendored 内容重新暂存你的改动会无冲突、无警告地消失。配置键则按构造天然存续。两个键均可选且都是剩余上下文窗口的百分比——数值越大触发得越早。键缺失时解析为上述默认值现有项目无需任何改动即可获得该行为。完整键表可在 docs/CONFIGURATION.md 中查到hooks.context_warnings默认true、hooks.context_warning_threshold默认35、hooks.context_critical_threshold默认25。解析规则永不抛错按表降级配置读取逻辑位于 gsd-context-monitor.js阈值解析函数resolveThresholds在 gsd-context-monitor.js。钩子从不阻塞工具调用因此绝不会因坏值抛错——它降级配置解析结果键缺失默认值35 / 25非数字或超出 0-100该键自己的默认值解析后critical warning两个都回退默认值——不一致的配对没有可读含义只兑现其中一侧等于静默丢弃另一侧warning为 0或critical为 100总是两个都回退默认值。这些在范围内但没有合法搭档——没有比 0 更低的数也没有比 100 更高的数critical warning永远不可能成立。config-set在写入时就会拒绝它们而不是存一个钩子总会丢弃的值注意上表两行是不同的规则且按顺序组合先用不可用值替换为其自身默认值再检查配对。因此context_warning_threshold: 150context_critical_threshold: 30解析为35 / 30而非 35 / 25——30 可用且 30 35 成立。同理context_warning_threshold: 20单独设置时与默认 critical 25 不一致回退为 35 / 25测试用例 明确锁定此行为。当任一键跨过另一键时两个键要一起调。配对检查比较的是解析后的值所以只覆盖一个键也会与另一键的默认值比对。gsd-tools config-set对每个键单独校验 0-100 域但故意不强制配对它每次调用只写一个键两步调优在磁盘上可能短暂不一致——从 35 / 25 调到 20 / 10若先降 critical 则全程合法若先降 warning 则中途不一致。写入端若强制配对就会拒绝这个中间态并强制某种顺序gsd-context-monitor.js 注释详述了这一设计取舍。数值校验使用Number.isFinite类型严格字符串30与布尔true都会被拒绝再加上 0-100 域检查。测试文件 tests/perf-317-context-monitor-fs.test.cjs 用 7 类坏值字符串、超域 150、负数、null、布尔、数组、对象逐项验证不可用输入永不提前触发、永不抛错同一文件还用 fast-check 属性测试#4285锁定了resolveThresholds在整个数值域上的不变量L2907-L3126。作用域只读根项目配置监控钩子只读取cwd/.planning/config.json不查询子项目或 workstream 配置。但gsd-tools config-set在环境变量选中作用域时会写入作用域配置——于是出现作用域写入成功、监控钩子仍用根值或根值缺省时的默认值的错位环境config-set写入位置两个变量都不设.planning/config.json—— 即钩子读取的文件GSD_PROJECTp.planning/p/config.jsonGSD_WORKSTREAMw.planning/workstreams/w/config.json两者都设.planning/p/workstreams/w/config.json这与hooks.context_warnings一直以来的根级作用域一致调优这些键请写入根.planning/config.json。一个前置条件必须已安装监控钩子两个键都需要已安装的监控钩子才生效。它们只被hooks/gsd-context-monitor.js读取没有其他消费者——在未安装该钩子的运行时上这两个键是惰性的config-set仍会存储并校验它们但没有钩子消费。Codex 就是今天的这种情况该钩子刻意不为 Codex 暂存因为它读取的指标桥文件只由hooks/gsd-statusline.js写入而 Codex 从不安装 statusline#2586。因此存储了一个值并不能证明触发点移动了——先确认该运行时的监控钩子已安装。防抖Debounce与 PreCompact 重置为避免向 Agent 重复轰炸警告防抖规则如下实现见 gsd-context-monitor.js首次警告总是立即触发后续警告之间需要间隔5 次工具调用DEBOUNCE_CALLS 5严重级升级WARNING → CRITICAL绕过防抖立即触发一次上下文压缩PreCompact重置该状态压缩后的循环如同全新会话——其首次警告立即触发WARNING → CRITICAL 升级再次绕过防抖。没有这次重置一旦 CRITICAL 触发过上述两条规则会在会话剩余时间内全部失效——因为升级判据是上一级别为 WARNING#3709。防抖计数与上一级别记录在警告哨兵文件claude-ctx-{session_id}-warned.json中读写都走硬化的readSentinel/writeSentinel路径见下文安全设计。PreCompact 重置的四件事PreCompact事件分支gsd-context-monitor.js同步完成四件事做什么为什么清空防抖计数与上次级别压缩重启了上下文生命周期下一次攀升是新循环清空一次性 critical-session 守卫否则恢复面包屑resume breadcrumb仍在描述更早的擦肩而过而不是真正终结本次运行的耗尽#1974删除 statusline 指标桥文件它保存着压缩前的读数而指标只在 60s 内新鲜——压缩后立刻用它触发警告方向完全相反写入压缩水印claude-ctx-{session_id}-compacted.json仅删桥文件只能收窄过期读窗口statusline 每次渲染都会重写桥文件压缩期间落下的渲染会用当前时间戳重建压缩前读数。水印记录压缩的开始时刻钩子丢弃其之后 60s 宽限窗口内的所有读数无时间戳0 或缺失的读数同样丢弃水印机制把竞态收窄而非关闭60s 是启发式边界而非实测上限运行超过窗口的压缩仍可能被一次同时通过水印与过期两道关卡的渲染跟随。成本有界但不只由窗口决定窗口内被丢弃的健康读数与被接受的读数行为完全一致窗口内真正的耗尽读数则是被跳过而非排队——其警告与 #1974 面包屑在窗口后的下一次读数上触发因此当后续读数到来时最多延迟窗口 被接受的时钟偏差实测无偏差时首恢复为水印 61s水印在 5s 偏差极限时首恢复为 66s若无后续读数则丢失——在窗口内结束的会话两者都不会记录。这种丢失是被接受的总好过信任一个可能是新时间戳下的压缩前值的读数。中止的压缩在同一周期内同样被静默事件本身无法区分中止与成功。超前阅读者时钟超过 5s 的水印被判定为异常偏离或时钟跳变的文件不得静默监控钩子而丢弃落在该偏差内的则被采信——这正是它可能延长延迟的原因。非普通常规文件的水印符号链接、目录、超大文件永不跟随状态栏桥文件与警告哨兵同理该目录下三个会话文件全部走同一硬化读取路径第 11 轮加固。一个按可预测路径放置的普通常规文件确实会在其窗口内被采信读取端检查对象形状与合理性不检查写入者身份因此同用户或在共享 sticky tmpdir 中跨所有者放置的水印每次最多静默监控钩子窗口 被接受的偏差65s——这与警告哨兵在同路径携带的残余风险一致由窗口封顶拒绝它需要所有权检查那是与当前文件不同的另一项策略。重置的性质值得知道的三点即使hooks.context_warnings为false重置照常执行。清理该状态是清理工作而非警告不产生任何输出——但配置在每次调用时重新读取一个禁用警告 → 压缩 → 重新启用的会话若不重置会复活陈旧状态。PreCompact在压缩之前触发。若压缩被中止状态已被重置。后果轻微多一次立即警告且面包屑守卫重新武装之后更新的面包屑可以替换旧值。重置只覆盖压缩。没有任何其他上下文收缩路径/clear、复用 session id 的会话重启会触发PreCompact因此以存续session_id为键的状态会活过这些路径接入SessionStart是独立的工作。所有操作都是 best-effort重置、截断回退、水印写入全部静默降级绝不导致压缩失败。Architecture数据流全景Statusline Hook (gsd-statusline.js) | writes v /tmp/claude-ctx-{session_id}.json ^ reads | Context Monitor (gsd-context-monitor.js, PostToolUse/AfterTool) | injects v additionalContext - Agent sees warning三个会话文件各司其职桥文件是单向指标通道警告哨兵记录防抖状态压缩水印记录压缩开始时刻。其中水印读取有专门的合理性门gsd-context-monitor.js水印时间戳不超前当前时钟超过WATERMARK_SKEW_SECONDS5s、且读数时间戳不晚于水印 COMPACT_GRACE_SECONDS60s时才被采纳否则按无水印处理退回到纯 60s 过期判断。读数时间戳缺失/为零/为垃圾值时同样被丢弃——一旦发生过压缩无时间戳的读数无法证明自己在压缩之后!()而非的写法正是为此。与 GSD 的集成状态保存与恢复面包屑/gsd-pause-work保存执行状态WARNING 消息建议使用它CRITICAL 消息指示立即保存状态。该命令在 commands/gsd/pause-work.md 中定义为创建.continue-here.md交接文件跨会话保留完整工作状态涵盖当前阶段检测、完整状态收集位置、已完成/剩余工作、决策、阻塞项、交接文件写入、WIP 提交与恢复指引。CRITICAL 自动记录会话状态#1974当 GSD 激活存在.planning/STATE.md且级别为 CRITICAL 时钩子以 fire-and-forget 子进程调用gsd-tools state record-session --stopped-at ...把面包屑写入 STATE.md 供/gsd:resume-work使用gsd-context-monitor.js。该动作每个 CRITICAL 会话只触发一次由warnData.criticalRecorded守卫避免每次防抖周期反复覆盖崩溃时刻记录。面包屑文本形如context exhaustion at 71% (2026-10-08)criticalStoppedAtL223-L225日期取操作者本地日经时钟缝隙尊重GSD_NOW_MS构建库缺失时回退主机本地日绝不取 UTC 日。安装与设置两个钩子在npx opengsd/gsd-core安装期间自动注册正常情况无需手动步骤。钩子配置细节、阈值覆盖与手动注册示例见 Configuration。简要参考statusline 钩子在settings.json中注册为statusLinecontext monitorgsd-context-monitor.js注册为PostToolUse钩子Antigravity CLI 为AfterTool两条注册项都使用运行安装器的绝对 Node 可执行文件路径Windows PowerShell 下带引号的可执行路径需加前缀调用。可用gsd-tools config-set写入阈值每次调用写一个键gsd config-set hooks.context_warning_threshold 45 gsd config-set hooks.context_critical_threshold 30注意 docs/CONFIGURATION.md 的边界说明config-set拒绝context_warning_threshold: 0没有 critical 值能与 0 配对与context_critical_threshold: 100没有 warning 值能配对。安全设计永不阻塞静默降级钩子的安全底线在 gsd-context-monitor.js 与 L552-L557 声明崩溃策略为ALLOWfail-open一切错误最终静默退出。具体包括整体 try/catch出错静默退出——损坏的监控器不应破坏 Agent 的工作流从不阻塞工具执行——ON_CRASH HOOK_ON_CRASH.ALLOW一个咨询性上下文警告的丢失远比卡住 Agent 的工作便宜#3911/ADR-3889过期指标超过 60s被忽略L413-L415桥文件缺失优雅处理子代理、全新会话直接静默退出压缩永不被本钩子阻塞若会话状态文件无法删除如 Windows 上文件句柄被占用钩子尝试原地把文件截断为空——后续读取把空文件当作文件不存在处理JSON.parse()必然抛错与删除同效——其余错误一律吞掉。截断是 best-effort 而非保证若那次打开也被拒绝或路径不是永不跟随的普通常规文件原文件存续、陈旧状态在该会话内持久。干净退出永远优先于清理状态stdin 超时守卫stdin 10s 内未关闭Windows/Git Bash 管道问题、慢速 Claude Code 大输出静默退出而非挂起#775、#1162哨兵文件硬化第 4/7/9/10/11 轮加固三个会话文件全部经由readSentinellstat 先验普通常规文件、拒绝链接/FIFO/目录/超大文件、O_NOFOLLOW封堵 lstat→open 替换竞态、4096 字节上限防巨型文件拖慢同步读、bytesRead完整校验防读取中收缩与writeSentinelunlink 后O_EXCL创建只落在本进程新建的常规文件上带进度检查的写循环防短写读写。这在共享 sticky tmpdir 中把被植入的符号链接指向 FIFO 导致同步读无限阻塞这类静默监控与停滞原语关在门外输出信封白名单#2289additionalContext信封只对注入能力事件PostToolUse、Antigravity 方言的AfterTool有效。Codex 在Stop/SubagentStart/SubagentStop/PreCompact下也注册了本钩子那些事件拒绝该信封hook returned invalid stop hook JSON output。实现用正向白名单只有注入能力事件才输出缺失/未识别事件名退出 0 且无输出L535-L551。Gemini 方言保留缺失事件名时的AfterTool回退GEMINI_API_KEY已设置时。所有上述副作用防抖计数、一次性 critical-session 记录无论是否输出都已执行完毕——静默事件 ≠ 跳过记账。小结Context Window Monitor用一条状态栏写、监控钩子读、additionalContext 注入的桥文件数据流把上下文余量从用户可见变成 Agent 可见35%/25% 双阈值可按项目在.planning/config.json中调优带类型严格的逐键回退与配对校验防抖与PreCompact水印机制在避免轰炸与压缩后不误报之间取得平衡而 fail-open 的崩溃策略、哨兵文件硬化与输出白名单保证了在任何宿主、任何异常下它都只是一个建议性的警告器永远不会阻塞或破坏 Agent 的工作。相关文档Architecture、Configuration、docs index。赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐让 Agent 自己感知上下文危机get-shit-done 的 Context Window Monitor 钩子深度解析让 Agent 自己感知上下文危机get shit done 的 Context Window Monitor 钩子深度解析 在 Claude Code /人工智能AI 应用提示工程开发工具工作流自动化AI Agentget-shit-done 上下文窗口监控Context Window Monitor让 Claude Code / Gemini CLI 的 Agent 感知并安全应对上下文耗尽get shit done 上下文窗口监控Context Window Monitor让 Claude Code / Gemini CLI 的 Agent人工智能AI 应用提示工程开发工具工作流自动化AI AgentDeepSeek Harness 的 tmux 位置上下文让 Agent 感知自身 session、window 与 pane 位置的设计与实现DeepSeek Harness 的 tmux 位置上下文让 Agent 感知自身 session、window 与 pane 位置的设计与实现 导读 在 t人工智能AI AgentAgent 框架DeepSeek上一篇Online-disk-direct-link-download-assistant终极解决方案让你告别网盘限速烦恼下一篇D3KeyHelper终极指南如何轻松玩转暗黑破坏神3自动化战斗创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考