GSD 分层帮助系统解析:/gsd:help 主题路由与分段提取机制
GSD 分层帮助系统解析:/gsd:help 主题路由与分段提取机制
导读
本文深入剖析 get-shit-done(GSD)项目的分层帮助系统,聚焦 get-shit-done/workflows/help/modes/topic.md 这一主题路由与分段提取的元工作流。它解决了"在超过 1400 行的完整命令参考中,如何让用户一条命令直达目标小节"的问题:通过一张别名解析表把 debug、planning 之类的口语化主题映射到完整参考文档 full.md 的精确章节,并按完整/紧凑两种作用域执行文本提取。读完本文,你将掌握 GSD 帮助系统的四层模式(brief / default / full / topic)的完整路由链路、主题别名表的全部映射关系、分段提取的三类规则(单章节、多章节拼接、子块锚定),以及背后由 tests/feat-3039-help-tiered.test.cjs 锁定的契约约束。
一、背景:从单一帮助文档到分层模式
在 feature #3039 之前,GSD 的帮助是一个约 747 行的单一大文件。当用户只需要回忆某个命令的签名时,输出整份参考既浪费上下文窗口,也不利于快速查阅。重构后,帮助系统被拆分为"1 个调度器 + 4 个模式文件":
| 文件 | 职责 | 触发方式 |
|---|---|---|
| get-shit-done/workflows/help.md | 渐进式披露调度器(约 30 行),根据 $ARGUMENTS 决定加载哪个模式文件 |
所有 /gsd:help 请求的入口 |
| get-shit-done/workflows/help/modes/brief.md | 约 10 行的一行式命令速查(≤ 30 行预算) | /gsd:help --brief |
| get-shit-done/workflows/help/modes/default.md | 一页式新手导览(≤ 70 行预算),包含"Topics:"列表 | /gsd:help(无参数) |
| get-shit-done/workflows/help/modes/full.md | 完整命令参考(≥ 600 行、≤ 1500 行预算) | /gsd:help --full |
| get-shit-done/workflows/help/modes/topic.md | 主题解析表 + 分段提取规则(本文主角) | /gsd:help <topic> 或 /gsd:help --brief <topic> |
关键设计原则是延迟加载(lazy-load):调度器只读取与 $ARGUMENTS 匹配的那一个模式文件,然后原样输出其 <reference> 块内容。四个模式文件各自恰好包含一个 <reference> 块,运行时输出的就是这些文件的正文本身——测试注释中称之为"source-text-is-the-product"(源码文本即产品)。
二、主题解析表:35 组别名的完整映射
topic.md 的核心是一张"主题解析表"(Topic resolution table),它把用户在命令行输入的口语化别名,不区分大小写地映射到 full.md 中的精确章节标题。别名匹配规则为:忽略大小写匹配;若存在单个前导 -- 则先剥除(因此 debug 与 --debug 等价)。
完整映射关系如下(左列为规范别名,右列为提取目标):
| 主题别名 | full.md 中的章节 |
|---|---|
workflow, core, core-workflow |
## Core Workflow(整节,直到 ### Quick Mode 结束) |
init, new-project |
### Project Initialization |
map, map-codebase |
### Project Initialization 下的 /gsd:map-codebase 块 |
discuss, discuss-phase |
### Phase Planning 下的 /gsd:discuss-phase 块 |
plan, planning, plan-phase |
### Phase Planning |
execute, exec, execute-phase |
### Execution |
progress, route |
### Progress Tracking 加 ### Smart Router |
quick, quick-mode |
### Quick Mode |
fast |
### Quick Mode 下的 /gsd:fast 块 |
phase, phases, roadmap |
### Roadmap Management |
milestone, milestones |
### Milestone Management 加 ### Milestone Auditing |
session, pause, resume |
### Session Management |
debug, debugging |
### Debugging |
spike |
### Spiking & Sketching 下的 /gsd:spike 与 /gsd:spike --wrap-up 块 |
sketch |
### Spiking & Sketching 下的 /gsd:sketch 与 /gsd:sketch --wrap-up 块 |
spike-sketch, experiments |
### Spiking & Sketching |
capture, notes, todos |
### Capturing Ideas, Notes, and Todos |
verify, verify-work, uat |
### User Acceptance Testing 加 /gsd:audit-uat 块 |
ship, pr |
### Ship Work 加 /gsd:pr-branch 块 |
review, peer-review |
### Ship Work 下的 /gsd:review 块 |
audit, auditing, audit-milestone |
### Milestone Auditing |
config, settings, configuration |
### Configuration |
cleanup |
### Utility Commands 下的 /gsd:cleanup 块 |
update |
### Utility Commands 下的 /gsd:update 块 |
files, structure, layout |
## Files & Structure |
modes, interactive, yolo |
## Workflow Modes |
planning-config |
## Planning Configuration |
workflows, common-workflows, examples |
## Common Workflows |
help |
## Getting Help |
这张表有三类提取目标,对应三种粒度:单章节(如 debug → ### Debugging)、多章节"加"连接(如 milestone → 两个 H3 章节依次输出)、子块锚定(如 map → 定位到 ### Project Initialization 内以 **\/gsd:map-codebase`** 加粗行开头的块)。default.md中对外宣传的workflow、planning、execute、quick、debug、capture、ship、config、milestones、spike、sketch、review、audit、progress` 这些主题别名,全部能在上表中找到对应识别项——这是测试强制保证的表面契约。
三、输出规则:七步精确执行协议
topic.md 以 7 条编号规则定义了完整的执行流程,任何 AI 运行时都必须严格遵循:
规则 1 — 参数解析:从 $ARGUMENTS 中检测 --brief(或短形式 -b)标志,命中则选择紧凑作用域(compact scope),否则为完整作用域(full scope)。剥除标志后,剩余 token 去掉单个前导 -- 即为主题别名。
规则 2 — 别名解析:将别名对照解析表查表匹配。
规则 3 — 无匹配兜底:若查不到,输出一行错误信息,随后输出逗号分隔的规范主题名列表(取左列每行的第一个别名、去重),并建议用户使用 /gsd:help --full 查看完整参考,然后停止。也就是说,未知主题会打印可识别的主题清单,而不是静默失败——这与 docs/COMMANDS.md 中"Unknown topics print the recognized list"的说明一致。
规则 4 — 路由前导行:匹配成功后,先输出一行解析路由前导(resolved-routing preamble),让用户明确看到"哪个别名匹配到了哪个章节、以什么作用域输出":
**Topic:** `<alias>` → `<heading>` *(scope: full | compact)*
这里 <alias> 使用左列规范别名,<heading> 使用表中匹配单元格的字面章节文本,并声明即将输出的作用域。测试文件 tests/feat-3039-help-tiered.test.cjs 明确注释了这一设计源于 trek-e review finding #3:路由必须在输出中显式可见,用户才能判断自己输入的别名被解析成了什么。
规则 5 — 读取与提取:读取 full.md,剥除 <reference>/</reference> 包裹标签(绝不输出它们),然后按匹配单元格的提取规则与作用域执行提取(详见下一节)。
规则 6 — 收尾行:章节内容输出完毕后,追加一行固定收尾:
More: /gsd:help --full · /gsd:help <topic> · /gsd:help --brief <topic>
规则 7 — 纪律约束:不输出任何项目特定评论,不追问用户。模式文件的 <purpose> 块中也反复强调"No additions, no surrounding chrome"。
四、分段提取机制:完整作用域 vs 紧凑作用域
提取是 topic.md 中最精密的逻辑,按匹配单元格的类型分为三种情形,每种情形都受作用域调制:
4.1 单章节(Single section)
单元格只含一个 `## Heading` 或 `### Heading` 时:
- 完整作用域:从该标题开始,输出到(不含)下一个同级或更高级别标题为止,即整节内容。
- 紧凑作用域:输出标题后,仅取节内第一条以
**\/gsd:...`**加粗的命令签名行及其后紧随的一行非空行(一句话摘要)。若该节没有加粗的/gsd:` 行,则退化为输出标题 + 第一段正文。
4.2 多章节拼接(Multiple sections joined by "plus")
单元格用 "plus" 连接多个章节(如 progress → ### Progress Tracking plus ### Smart Router)时,按文档顺序对每个章节依次应用 4.1 的规则,顺序输出且章节间不留空隙。
4.3 子块锚定(Sub-block)
单元格写作 the /gsd:X block under ### Heading 或 the /gsd:X ... blocks under ### Heading 时(如 map、discuss、fast、spike、cleanup 等),在指定章节内以每个 **\/gsd:X ...`**` 加粗行作为起点定位:
- 完整作用域:从该加粗行开始,到下一个
**\/gsd:...`**` 加粗行或下一个标题(以先到者为准)之前结束。 - 紧凑作用域:只输出加粗行及其后紧随的一行非空摘要。
单元格列出多个子块时(如 spike 同时含 /gsd:spike 与 /gsd:spike --wrap-up 两块),按顺序依次输出。
4.4 作用域的实际效果对比
以 debug 主题为例,两种作用域的输出差异:
/gsd:help debug(完整作用域)输出### Debugging整节,包括/gsd:debug [issue description] [--diagnose]的完整说明、--diagnose标志解释、行为特征(持久化调试状态、科学方法调查、跨/clear存活、归档机制)以及全部 Usage 示例。/gsd:help --brief debug(紧凑作用域)只输出标题 + 签名行/gsd:debug [issue description] [--diagnose]+ 紧跟的一句话摘要("Systematic debugging with persistent state across context resets.")。
紧凑作用域的设计动机是让"签名 + 一句话摘要"这种快速查证场景不占用过多上下文窗口,实现真正的按需轻量检索。
五、调度器路由与冲突消解
从 topic.md 往上一层,get-shit-done/workflows/help.md 是负责渐进式披露的调度器,其参数解析规则定义了完整的路由矩阵:
当 $ARGUMENTS 为 |
读取 |
|---|---|
--brief(或 -b)单独出现 |
workflows/help/modes/brief.md |
--full(或 -f、--all)单独出现 |
workflows/help/modes/full.md |
| 空 / 未设置 | workflows/help/modes/default.md |
--brief <topic>(或 -b <topic>) |
topic.md,紧凑作用域(签名 + 一句话摘要) |
其他任意内容——裸主题、--full <topic>、或带前导 -- 的主题 |
topic.md,完整作用域(整节) |
调度器的参数解析规则值得注意的细节:
$ARGUMENTS需先 trim 并转小写后再识别长形式、短形式和明显的别名形式。- 裸 token 如
debug、--debug、capture、workflow、config一律视为主题,路由到topic.md。 - 冲突消解:
--brief与--full互斥——若二者同时出现且不带主题,优先--full。 - 组合语义:
--brief搭配主题时,topic.md以紧凑作用域执行;--full搭配主题时以完整作用域执行(即主题的默认行为)。当向topic.md透传参数时,必须保留--brief标志,因为该标志是topic.md判断作用域的唯一依据。
这条路由链路的末端是命令垫片 commands/gsd/help.md:一个带有 argument-hint: "[--brief | --full | <topic> | --brief <topic>]" frontmatter 的薄层,通过 @~/.claude/get-shit-done/workflows/help.md 的 execution context 引用调度器,并把 $ARGUMENTS 原样透传。argument-hint 明确对外宣传可组合的 --brief <topic> 形式,保证用户在输入 /gsd:help 时能通过补全提示发现这个能力。
六、契约保障:测试如何锁定这套机制
主题路由不是松散约定,而是被 tests/feat-3039-help-tiered.test.cjs 用九组测试硬性锁定的部署契约。文件头注释点明了核心思想:workflows/help/modes/*.md 本身就是帮助输出,运行时发出的就是这些文件的文本,因此断言其结构即是在测试部署契约本身。值得关注的契约点包括:
- 文件结构:四个模式文件各含且仅含一个
<reference>块(以行首锚定计数,避免<purpose>块中的散文误计)。 - 体积预算:
brief.md≤ 30 行、default.md≤ 70 行("一屏"预算);full.md≥ 600 行(防止意外缩水导致--full静默丢内容)且 ≤ 1500 行(LARGE 层级上限,因full.md位于子目录、未被非递归的 workflow-size-budget 测试覆盖,故在此单独设限)。 - 调度器契约:
<progressive_disclosure>块恰好 5 行路由(4 个基础层 + 1 个--brief <topic>组合行);--brief路由到brief.md、--full路由到full.md、空参数路由到default.md、主题参数路由到topic.md。 - 冲突消解被文档化:调度器必须写明"无主题时
--brief+--full并存则优先--full"、"--brief <topic>以紧凑作用域调用topic.md"、"裸主题 /--full <topic>以完整作用域调用"以及"透传时保留--brief"。 - 命令垫片契约:
commands/gsd/help.md必须引用$ARGUMENTS、声明argument-hint:frontmatter、且在提示中宣传--brief <topic>组合形式。 - 路由可见性:
topic.md必须包含**Topic:**前导模板(含<alias>、<heading>、scope: full | compact)与"签名 + 一句话摘要"的紧凑作用域描述。 - 别名表完整性(最重要的三条交叉验证):
topic.md别名表中引用的每个章节标题都必须真实存在于full.md(防止映射到不存在的标题);- 别名表中的每个
/gsd:*子块 token 都必须出现在full.md中(这是对 review finding #2 的修复——子块别名引用加粗行锚点,必须逐一断言 token 存在); full.md的每个 H2/H3 标题要么被别名覆盖,要么显式列入 INTENTIONAL_ORPHANS 白名单(## Quick Start、## Staying Updated、### Utility Commands、## Additional Commands及其全部子章节、### Namespace Routers等)。这意味着贡献者新增章节时,要么为其补一个别名,要么显式声明它是故意孤立的。
- 表面契约:
default.md的Topics:行中宣传的每个别名都必须在topic.md的别名表中可识别(且数量 ≥ 5),防止"宣传了却不支持"的断裂。
七、实战用法与主题速查
7.1 五种形态一览
/gsd:help # 一页式新手导览(默认)
/gsd:help --brief # 约 10 行顶级命令速查
/gsd:help --full # 完整参考(每个命令、每个标志)
/gsd:help debug # 只输出 debug 对应章节(完整作用域)
/gsd:help --brief debug # 紧凑查证:签名 + 一句话摘要
7.2 典型场景
- 回忆单个命令签名:
/gsd:help --brief plan-phase,输出标题 +/gsd:plan-phase <number> [--research] [--skip-research] ...签名行 + 一句话摘要,不浪费上下文。 - 完整理解一个功能区:
/gsd:help milestone,按文档顺序拼接### Milestone Management与### Milestone Auditing两节,一次性看到new-milestone、complete-milestone、audit-milestone的完整说明。 - 只看某个子命令块:
/gsd:help fast,只提取### Quick Mode内/gsd:fast块的说明,避开同节的/gsd:quick内容。 - 探索主题清单:输入一个不存在的主题(如
/gsd:help foobar),会得到一行错误提示 + 去重后的规范别名清单,相当于免费获得一份主题索引。 - 模糊意图路由:如果记不清命令名,
/gsd:progress --do "<描述>"的智能路由器会把自然语言意图派发到正确的/gsd-*命令——帮助系统与其互为补充,前者解决"该用什么命令",后者解决"这个命令怎么用"。
7.3 主题覆盖范围速查
别名表共覆盖 35 行映射,可归为几大类:
- 生命周期类:
init/new-project、milestone、phase/roadmap、cleanup、update; - 规划执行类:
discuss、plan/planning、execute、quick、fast; - 质量验证类:
verify/uat、review、audit、debug; - 探索实验类:
spike、sketch、capture/notes/todos; - 交付发布类:
ship/pr; - 状态路由类:
progress/route、session/pause/resume; - 配置与参考类:
config/settings、planning-config、files/structure/layout、modes、workflows、help。
八、维护指南:如何安全扩展主题
从测试契约可以反向推导出扩展这套系统的安全流程:
- 在
full.md中新增或调整章节后,必须检查topic.md别名表:要么为新章节补别名行,要么把章节标题加入INTENTIONAL_ORPHANS白名单(tests/feat-3039-help-tiered.test.cjs 会拦截任何"既无别名又不入白名单"的孤儿标题)。 - 新增命令块时,若希望它可通过子块别名访问,需同步在
topic.md别名表的单元格中引用其**\/gsd:...`**加粗行,并保证该 token 字面存在于full.md`。 - 调整 default.md 的
Topics:宣传列表时,确保每个新别名都能在topic.md中被识别。 - 保持体积预算:
brief.md与default.md必须维持"一屏"量级,full.md不得低于 600 行——任何删除内容的行为都会被测试标记为"可能丢失了--full内容"。
这套"文档即产品、测试锁契约"的机制,让帮助系统在拥有 60+ 斜杠命令的庞大规模下依然保持渐进式披露的良好体验:新用户从一页导览起步,老用户用 --brief 十行速查,深度使用者用 --full 掌握全部,而所有人在任意时刻都能用主题路由直达自己关心的那一个章节。
相关文件索引
- get-shit-done/workflows/help/modes/topic.md — 主题解析表与提取规则(本文主角)
- get-shit-done/workflows/help/modes/full.md — 完整命令参考(提取的源文档)
- get-shit-done/workflows/help/modes/brief.md — 一行式速查模式
- get-shit-done/workflows/help/modes/default.md — 新手导览模式(含 Topics 宣传列表)
- get-shit-done/workflows/help.md — 渐进式披露调度器(路由矩阵与冲突消解)
- commands/gsd/help.md — 命令垫片(透传
$ARGUMENTS并宣传组合形式) - tests/feat-3039-help-tiered.test.cjs — 分层帮助契约测试(九组断言)
- docs/COMMANDS.md —
/gsd-help命令的用户文档