planning-with-files 状态查询指南:Hermes /plan-status 命令与 planning_with_files_status 工具深度解析
【免费下载链接】planning-with-filesPersistent file-based planning for AI coding agents and long-running tasks. Crash-proof markdown plans, session recovery after /clear and compaction, per-turn re-injection against context rot, deterministic completion gate. Manus-style. Install from npm, the Claude Code plugin marketplace, or npx skills. Codex, Cursor, OpenCode, 60+ agents.项目地址: https://gitcode.com/GitHub_Trending/pl/planning-with-files
planning-with-files 为 AI 编码 Agent 提供基于文件的持久化计划机制,而/plan-status(等价于/pwf-status)正是这套机制中"随时确认自己处在哪个计划、做到哪一步"的核心入口。本文以 .hermes/commands/plan-status.md 为骨架,结合 Hermes 插件源码,完整讲解状态查询命令的定义、底层planning_with_files_status工具的 JSON 输出结构、阶段统计与计划解析规则,帮助你读懂任何一次状态快照,并在 /clear、上下文压缩、多会话等场景下快速恢复对计划的控制。
一、命令是什么:一条来自命令文件的精确定义
.hermes/commands/plan-status.md是整个功能的最小、权威定义,全文只有两条信息:frontmatter 中的description,以及一条可执行的指令:
--- description: "Show Hermes planning-with-files status for the current project." --- Run `planning_with_files_status` in the current project directory and present the result as a compact status summary.也就是说,当用户在 Hermes 中输入/plan-status时,Agent 被要求:
- 在当前项目目录(即 Hermes 解析出的运行时 cwd)调用
planning_with_files_status; - 把返回的结果整理成一份紧凑的状态摘要呈现给用户。
与之并列的还有 .hermes/commands/plan.md(负责初始化并进入 planning 工作流),二者一个负责"建计划",一个负责"看状态"。根据 .hermes/skills/planning-with-files/SKILL.md,插件同时注册了/pwf与/pwf-status两个斜杠命令,/pwf-status与/plan-status报告同一个活跃计划;而/plan是 Hermes 自带的技能,不会被本插件遮蔽。
二、底层工具链:从命令到 JSON 的两层调用
/plan-status不是魔法,它最终落到插件工具 tools.py 中定义的两个函数:
def planning_with_files_status(cwd: str = "") -> str: project_dir = normalize_cwd(cwd) result = summarize_status(project_dir) return json.dumps(result, ensure_ascii=False)- 参数
cwd可选,为空时取进程当前目录(normalize_cwd会做expanduser+resolve,详见 paths.py); - 返回的是序列化后的 JSON 字符串,而非纯文本,这是为了让 Agent 能稳定解析字段;
- 真正组装状态内容的是 planning_files.py 中的
summarize_status(project_dir)。
在 plugin.yaml 中,planning_with_files_status与planning_with_files_init、planning_with_files_check_complete一起被声明为插件对外暴露的三个工具,配套的三个钩子pre_llm_call、post_tool_call、pre_verify则负责每轮注入计划、写文件后提醒、完成门控。
三、状态快照的完整字段:summarize_status 输出逐项解读
summarize_status(planning_files.py 中的实现)是整个命令的数据来源。先看"没有计划"的分支:当resolve_plan_dir返回None时,返回:
{ "exists": false, "message": "No planning files found. Run planning_with_files_init first.", "project_dir": "...", "files": { "task_plan.md": false, "findings.md": true, "progress.md": true } }注意这里findings.md/progress.md仍会单独探测项目根目录,即使task_plan.md不存在——这有助于判断是"完全没有初始化"还是"只有半套文件"。
当存在活跃计划时,返回的 JSON 包含以下字段:
| 字段 | 含义 | 来源 |
|---|---|---|
exists | 是否找到活跃计划 | resolve_plan_dir |
project_dir | 解析后的项目根目录 | normalize_cwd |
plan_dir | 活跃计划所在目录 | resolve_plan_dir |
plan_id | 计划标识:slug 名,legacy 模式为"root" | plan_id_for |
mode | 生效模式令牌,无令牌时为"legacy" | mode_tokens |
attested | 是否存在鉴证文件(计划是否被锁定) | attestation_path_for |
current_phase | 当前阶段名称 | extract_current_phase |
counts | 各状态阶段计数 | phase_counts |
files | 三个计划文件是否存在 | 文件系统探测 |
recent_progress | progress.md末尾 20 行 | tail_lines(PROGRESS_TAIL_LINES=20) |
plan_preview | task_plan.md开头 30 行 | head_lines(PLAN_PREVIEW_LINES=30) |
errors_logged | ## Errors Encountered表格中的数据行数 | count_error_rows |
常量定义见 constants.py。其中recent_progress的 20 行尾巴在注入上下文时还会经过normalize_wall_clock处理:把 ISO-8601 时间统一压平成T00:00:00,保证同一输入在不同轮次产生逐字节一致的注入内容,避免破坏 prompt 缓存。
四、阶段统计的三种格式:phase_counts 的解析策略
counts是状态摘要里最核心的一组数字。phase_counts(实现见 planning_files.py)按优先级支持三种计划书写风格:
格式一:### Phase标题 +**Status:**字段(默认模板风格)
### Phase 3: Implementation - [ ] Execute the plan step by step - **Status:** in_progress解析规则:以### phase开头的行计入total;包含**status:**的行按关键词归类——complete、in_progress、failed/blocked、pending。
格式二:Markdown 表格
| Phase | Status | |-------|--------| | Setup | complete |解析规则:以|开头和结尾的行,去掉首尾竖线后拆分单元格,第二列为状态值;表头(第一格为phase/error或全是-)会被跳过。
格式三:行内括号标记
[complete] Phase 1 [in_progress] Phase 2解析规则:直接统计[complete]、[in_progress]、[pending]三个标记的出现次数。
extract_current_phase的查找顺序与之配套:先读## Current Phase小节下第一行有效内容(跳过注释、WHAT:/WHY:/EXAMPLE:等引导行);若不存在,找第一个带**status:** in_progress的### Phase标题;再退化为表格中状态为in_progress的行;最后回退到第一个### Phase,全部失败则返回"No phase found"。这保证了无论用户用哪种风格维护 task_plan.md 模板(其中规定了 Goal、Next Step、Current Phase、Phases、Key Questions、Decisions Made、Errors Encountered、Notes 结构),状态命令都能给出有意义的"当前阶段"。
五、状态背后的计划解析:resolve_plan_dir 的优先级与护栏
summarize_status的第一步是resolve_plan_dir(project_dir),它的解析优先级(paths.py 实现)与 shell 版resolve-plan-dir.sh完全对齐:
- 显式
PLAN_ID环境变量:一旦设置即是"绑定"而非"提示"(issue #237),slug 能解析就直接采用;不能解析就立即失败,绝不回退到其他计划,防止一个字符的拼写错误导致静默切换计划; .planning/.active_plan指针:init_plan在创建命名计划时会写入YYYY-MM-DD-<slug>;.planning/下最新修改的<slug>/task_plan.md:按 mtime 取新;- legacy 根模式:项目根目录下的
task_plan.md。
每一步都有安全护栏:slug 必须匹配^[A-Za-z0-9_][A-Za-z0-9._-]*$,所选目录必须真实包含在.planning内(拒绝符号链接/junction 逃逸)。此外还有两条值得在状态输出中留意的规则:
- 嵌套根冲突:当 cwd 下存在活动计划、且其直接子目录里也有自己的活跃计划时,基于 cwd 猜测的解析会被拒绝(issue #212),此时
resolve_plan_dir返回None,状态命令会提示No planning files found——实际原因是歧义。解决方式是给线程钉住根目录:PWF_PLAN_ROOT=<绝对路径>或PLAN_ID=<slug>; - 根目录钉扎:
PWF_PLAN_ROOT必须指向存在的绝对路径目录,且不能是 UNC 路径、不能带链接组件,否则"fail closed"(什么都不注入),而不是错误回退。
六、模式与鉴证:mode、attested 字段怎么读
状态输出中的mode与attested直接反映了 v3 门控体系:
mode由mode_tokens(project_dir, plan_dir)计算:读取<plan_dir>/.mode与项目根.mode,二者取并集(提升严格性的令牌如autonomous、gate、inject-smart任一文件有即生效),而降低严格性的令牌plan-guard-off只有在 slug 与根都携带时才存活——一个 slug 计划永远无法关掉项目层面保持的保护(issue #238)。没有任何令牌时输出"legacy",即纯建议性计划;attested检查鉴证文件是否存在:legacy 根计划鉴证到./.plan-attestation,slug 计划鉴证到<dir>/.attestation,内容是一行小写 SHA-256 hex(write_attestation与attest-plan.sh行为一致)。鉴证存在的含义是:task_plan.md的当前内容已被哈希锁定,钩子注入的是"经过鉴证的快照"。
如果状态显示mode: gated,意味着该计划受pre_verify钩子门控:只要存在in_progress阶段、.stop_blocks计数未达到上限(环境变量PWF_GATE_CAP,默认 20)、且 ledger 有推进,Agent 就会被要求"完成或更新计划后再停"(决策表见evaluate_gate,hooks.py 中说明 Hermes 侧由agent.max_verify_nudges限制续跑次数,默认 3)。
七、把 JSON 变成"紧凑摘要":一份实用的解读清单
/plan-status的指令要求 Agent "present the result as a compact status summary"。基于上述字段,一份合格摘要应包含五件事:
- 计划身份:
plan_id(是root还是某个 slug)+mode+attested状态,一句话交代"我在哪个计划、什么模式、是否被锁定"; - 当前阶段:
current_phase原文,配合counts中的complete/total表达整体进度,如 "Phase 3: Implementation(in_progress,2/5 完成)"; - 文件齐全性:
files中三个布尔值,缺哪个一目了然; - 最近进展:
recent_progress的 20 行尾巴,直接转述最近一次记录的内容; - 错误登记:
errors_logged非零时提示"计划里登记了 N 条错误",提醒复盘,避免重复失败路径。
八、典型使用场景
- 会话被 /clear 或压缩之后:
/plan-status是成本最低的恢复入口——先看plan_id与current_phase,再读recent_progress,即可无缝接续,配合 session-catchup.py 的同项目会话记录可进一步还原上下文; - 多计划并存时:状态输出中的
plan_id能确认当前到底命中哪个 slug;若解析失败(嵌套歧义),按提示设置PLAN_ID或PWF_PLAN_ROOT钉住线程; - 开始复杂工作前:
/plan-status确认attested为真、counts无异常,再进入执行,让"计划-执行-记录"闭环从第一分钟就成立。
九、小结
/plan-status虽是一条一行指令,背后却是一整套确定性规则:从resolve_plan_dir的优先级与防逃逸护栏,到phase_counts对三种书写格式的兼容,再到mode_tokens的根目录模式地板与鉴证锁定。掌握本文的字段语义,你就能在任何 Agent 会话中把一行 JSON 翻译成对计划状态的确切判断——这正是 planning-with-files 在长时任务中"永不忘记计划"的基础设施之一。
【免费下载链接】planning-with-filesPersistent file-based planning for AI coding agents and long-running tasks. Crash-proof markdown plans, session recovery after /clear and compaction, per-turn re-injection against context rot, deterministic completion gate. Manus-style. Install from npm, the Claude Code plugin marketplace, or npx skills. Codex, Cursor, OpenCode, 60+ agents.项目地址: https://gitcode.com/GitHub_Trending/pl/planning-with-files
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考