ECC HUD 状态与会话控制契约:面向多 Harness 的 ecc.hud-status.v1 便携状态协议解析
【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC
这篇技术指南围绕 ECC(Everything Claude Code)架构文档 hud-status-session-control.md 定义的「HUD 状态与会话控制契约」展开:它是一套刻意与具体 Agent Harness 解耦的可移植状态载荷协议ecc.hud-status.v1,供 Claude Code statusline、Codex 面板、dmux 会话、OpenCode 运行与纯终端工作流共用一个稳定字段命名空间。读完本文,你将掌握协议顶层结构、会话控制词汇、同步契约的语义边界,以及 ECC 仓库中ecc status、ecc loop-status、ecc session-inspect、ecc-statusline四条现状实现如何把各自信号「投影」进同一个外层契约,为未来演进中的专属全屏 HUD 预留统一接口。
为什么需要一份"Harness 中立"的状态契约
在 ECC 的运行时环境中,执行状态分散在多个互不相同的表面上:Claude Code 的 statusline 通过 stdin 推送上下文与窗口压力;Codex 依赖自身面板;dmux 承载长时编排会话与 worker;OpenCode 每次运行产生独立 transcript;而纯终端工作流可能连图形界面都没有。若每个表面各自发明一套字段名,状态数据将无法在表面之间搬运,HUD 与交接(handoff)也无从谈起。
该契约的核心立场是:
- payload 以
schema_version: "ecc.hud-status.v1"为版本标识,顶层 section 集合保持稳定; - 顶层字段名被当作稳定的公共 API:任何 surface 都可以在不改字段名的情况下只发出部分数据(partial data);
- 缺数据是合法的:字段可以是
null、空数组或"unknown",生产者不得臆造不兼容的新名字。
由此,契约的价值不在于"全量强制",而在于公共字段形状 + 宽容的缺失语义。文档给出的规范样例位于 examples/hud-status-contract.json,它同时充当协议的手写示范与校验基准。
顶层字段总览:一个稳定的状态骨架
每个ecc.hud-status.v1payload 都维持以下稳定的顶层分区,任何实现都不得重命名或改变其语义:
| 字段 | 用途 | 主要数据源 |
|---|---|---|
context | 模型、harness、仓库、分支、worktree、会话 id 与上下文窗口压力 | statusline stdin、git、会话适配器 |
toolCalls | 近期工具调用计数、挂起调用、过期(stale)调用与最近一次工具事件 | loop-status、tool-usage.jsonl、hook bridge |
activeAgents | 当前 worker/子代理、运行时状态、分支、worktree、目标与交接路径 | dmux/编排快照 |
activeAgents | 当前 worker/子代理运行时状态、分支、worktree、objective 与 handoff 路径 | dmux/orchestration 快照 |
todos | 当前进行中任务与 todo 计数 | Claude todos、本地任务文件、计划元数据 |
checks | 本地与远程校验状态,能带命令或检查 URL 时附上 | CI、本地命令、发布门禁 |
cost | 会话花费、token 数、预算与趋势 | 成本追踪器、metrics bridge |
risk | 注意力(attention)状态、冲突压力、stale 调用、脏 worktree 与人工复核标记 | readiness 门禁、git、队列状态 |
queueState | GitHub PR/issue/discussion 计数、冲突队列、merge 队列与 stale-salvage 队列 | GitHub sync、work items |
sessionControls | 当前目标支持的运营商动作(operator actions) | ECC CLI、dmux、git/GitHub |
sync | Linear、GitHub 与 handoff 的发布状态 | 状态更新、work items、handoff writer |
渲染铁律:当某个 harness 无法提供某项信号时,消费者应当把缺失的 section 渲染为"不可用(unavailable)",绝不能渲染成健康的绿色——这对正确判断运行体是否真正健康至关重要,也是该契约与纯营销型状态页的本质区别。
从规范样例理解各分区形态
examples/hud-status-contract.json 展示了带具体值的完整 payload。例如context记录 harness、模型与仓库信息,并给出contextWindow的remainingPct与pressure:
"context": { "harness": "codex", "model": "gpt-5", "repo": "affaan-m/everything-claude-code", "branch": "main", "worktree": "/repo/everything-claude-code", "sessionId": "session-active", "contextWindow": { "remainingPct": 62, "pressure": "normal" } }toolCalls区分三类计数器:已发生的total、尚未返回的pending、以及超过时限的stale,lastTool记录最近一次工具名、状态与完成时间——stale 计数正是 scripts/loop-status.js 中--bash-timeout-seconds(默认 1800 秒)判定挂起 Bash 调用是否过期的直接产物。activeAgents以数组描述每个 worker 的状态机,todos用inProgress加counts结构呈现当前进行中任务与队列分布。
risk是整个契约中最"操作导向"的分区,它显式携带status、reasons、dirtyWorktree、conflicts与manualReviewRequired:
"risk": { "status": "attention", "reasons": ["release tag not published"], "dirtyWorktree": false, "conflicts": 0, "manualReviewRequired": true }queueState则横向聚合了 GitHub 公网队列(open PR/issue/discussion)、mergeQueue、conflictQueue与staleSalvageQueue——其中 stale-salvage 队列直接呼应了 ECC 对"陈旧工作回收"(stale PR salvage)的长效追踪设计。
会话控制词汇:operator 的最小动作集
契约规定了每个会话表面都应支持的最小会话控制词汇表,动作名对消费者来说是可编程的稳定 API:
| 控制 | 含义 |
|---|---|
create | 启动一个新的隔离运行、worktree 或编排计划 |
resume | 重新挂接到现有会话或历史目标 |
status | 只输出当前 payload,不修改任何状态 |
stop | 请求优雅停止,或将会话标记为已完成 |
diff | 显示当前工作树或 worker 的 diff |
pr | 打开或检视关联的 pull request |
mergeQueue | 展示可合并、被阻塞与等待检查项 |
conflictQueue | 展示需要整合的脏/冲突 PR 或 worktree |
该词汇表通过sessionControls分区暴露能力边界:
sessionControls.supported:列出当前 harness 实际可用的控制;sessionControls.blocked:解释哪些控制不可用及其原因,例如缺少 GitHub token、不存在 tmux 会话、或底层适配器只读。
在规范样例中,supported恰好枚举了完整八项、blocked为空数组;而在受限环境下,某个控制不可用时不应静默消失,而应出现在blocked并给出可诊断的理由字符串。status的语义被特别强调为"无副作用"——查询状态的动作绝不能反过来污染被观测的会话状态,这是它能够被反复轮询的前提。
同步契约:把"做过的事"沉淀为可证证据
sync分区刻意把三类持久化跟踪器分开,避免所有运行都被迫写 Linear issue 或 GitHub 评论:
- Linear:记录项目状态更新 id、健康度(如
atRisk),以及 issue 创建是否被工作区容量阻塞(issueCapacityBlocked); - GitHub:记录当前仓库、PR/issue/discussion 队列计数,以及与会话绑定的最新合并/打开 PR;
- handoff:记录持久化 Markdown 交接文件路径,以及最近一批变更后是否已写入(
written)。
这一点与该仓库的另一份架构契约 progress-sync-contract.md 互为表里:后者的「Real-time Boundary」明确规定,本地实时路径默认以文件为后端,node scripts/status.js --json与node scripts/work-items.js list --json负责向 HUD、handoff 或后续 Linear 同步暴露本地状态,任何后来引入的托管遥测(如 PostHog)都必须消费同一事件模型,不得变成第二套真相源。契约文档原文也强调:当 Linear issue 容量被阻塞时,payload 仍然可以通过 project update 与仓库内 handoff证明进度确实在发生——实时进度追踪因此不依赖任何单一外部系统。
四条现状实现:把分散信号投影进同一契约
文档明确列出 ECC 仓库中当前的四条实现,它们各自在不同粒度上产生或消费状态信号。结合源码,我们可以看清每条命令真实做了什么。
ecc status --json:从 SQLite 状态存储做全量盘点
scripts/status.js 的参数解析显示它支持--db <path>、--json|--markdown、--write <path>、--limit <n>与--exit-code。它查询 ECC SQLite 状态存储(state store),汇总活动会话、近期 skill 运行、安装健康度、待处理治理事件与关联 work item。命令行 help 明确写道"Use --exit-code to return 2 when readiness needs attention",即它能把"就绪性需要关注"翻译成进程退出码,供脚本化门禁消费。输出的人类可读形态包含每个会话的id [harness/adapterId] state、仓库根、启动时间与 worker 数——这天然对应契约中的context与activeAgents分区,而--write支持把同样的盘点落盘为可交接的持久产物。
ecc loop-status --json --write-dir <dir>:长时循环的注意力与实录快照
scripts/loop-status.js 面向"长时间运行的 agent 循环"设计。其参数面非常细:--json输出机器可读 JSON;--transcript <session.jsonl>直接检视单个 transcript;--bash-timeout-seconds(默认 1800s)决定挂起 Bash 调用何时被判为 stale;--wake-grace-multiplier(默认 2)是 ScheduleWakeup 的宽限倍率;--exit-code在检测到 attention 信号时退出码为 2;--watch/--watch-interval-seconds支持周期性刷新。
--write-dir <dir>会把index.json与每个会话的状态快照写入目标目录——这正是契约toolCalls(工具计数与 stale 判定)、risk(attention 信号)分区的现场数据来源。测试文件 tests/scripts/loop-status.test.js 覆盖了该扫描与快照逻辑,印证了上述参数语义是可测试的稳定行为。
ecc session-inspect <target> --write <path>:从 dmux 与 Claude 历史产出规范快照
scripts/session-inspect.js 提供的是"会话体检"式快照:目标(<target>)可以是 dmux/编排 plan 文件、dmux 会话名、claude:latest、具体 Claude 会话 id、直接指向 session 文件,甚至是skills:health、skills:amendify、skills:evaluate等技能改进体检目标。核心动作inspectSessionTarget来自scripts/lib/session-adapters/registry的适配器注册表(--list-adapters可枚举),--write <output.json>负责把结果原子落盘为规范会话快照——它的输出同样以ecc.hud-status.v1的外层形状为投影目标,是"dmux + Claude-history 适配器"这两类信号源进入统一契约的官方桥梁。
scripts/hooks/ecc-statusline.js:Claude Code 内的紧凑单行渲染
这是最贴近"当下正在发生什么"的表面。其注册方式不同于普通 hook:它作为statusLine命令写入~/.claude/settings.json,而非 hooks.json,由 Claude Code 运行时每行状态推送 stdin 数据驱动。示例配置见 examples/statusline.json,其中说明了安装方式、色彩阈值与依赖关系:
- 色彩阈值:上下文用量 <50% 绿、<65% 黄、<80% 橙、≥80% 红闪;
- 依赖:读取由
ecc-metrics-bridge.js的 PostToolUse hook 写入的桥接文件,两方必须同时安装才能完整显示指标; - 输出形态示例:
Opus 4.6 | Fixing auth bug | $1.23 47t 5f 15m | myproject ███████░░░ 68%。
读 scripts/hooks/ecc-statusline.js 源码可看到它的完整逻辑链:
sanitizeSessionId先净化会话 id,随后经readBridge读取指标桥文件、writeBridgeAtomic把剩余上下文百分比回写桥文件,供 context-monitor 消费(注意这里用到 scripts/lib/session-bridge.js 的原子写能力);readCurrentTask在CLAUDE_CONFIG_DIR/todos下按{sessionId}-agent-*.json前缀匹配最新文件,取in_progress状态 todo 的activeForm作为当前任务文本;buildContextBar引入AUTO_COMPACT_BUFFER_PCT = 16.5的"自动压缩缓冲",把 Claude Code 上报的剩余百分比折算为可用余量后再映射成十格彩色进度条,避免窗口即将触发 auto-compact 时仍显示满格;formatDuration把首个时间戳格式化为5s/12m/1h23m之类的紧凑时长;- 单行输出最终由 model、当前任务、指标段、目录名与上下文条拼接而成,通过
\x1b[2m\u2502\x1b[0m(dim 分隔符)分隔。
该脚本把契约中context(模型、目录、窗口压力)、todos(当前任务)、cost($1.23)、toolCalls(47t)与文件变更数(5f)压缩进一行可扫读文本,是"先于全屏 HUD 存在"的轻量可视化层。
消费约定与未来方向
契约文档在末尾给出了关键定位:ecc.hud-status.v1是这些 surface在 ECC 演进出专属全屏 HUD 之前可以先投影进去的共同外层契约。换言之,所有现状实现都有责任把各自的私有字段翻译成协议词汇,HUD 消费者只需理解一张稳定的 schema,而无需针对每种 harness 写分支判断。
对开发者而言,落地时可以遵循四条实用原则:
- 永远携带 schema_version,让未来 v2 可以平滑演进而不破坏旧消费者;
- 只发你有的信号,缺项用
null/[]/"unknown"表达,绝不发明同名异义的字段; - 把"不可用"渲染成不可用,宁可显式
unknown也不向 operator 谎报健康; - 动作语义保持一致,
status不产生副作用、stop优雅退出、create/resume只在支持的 harness 上暴露,并通过sessionControls.blocked解释受限原因。
这种"一份 schema、多个 surface、宽容缺失、证据优先"的设计,使 ECC 的状态可观测性不必绑定任何单一 IDE、终端或托管面板——它既服务今天的 statusline 与 CLI 盘点,也为明天真正属于自己的 HUD 预留了无需迁移的接口边界。
【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考