mcpField
B
blueprint-feature-tracker-sync

blueprint-feature-tracker-sync

github.com/laurigates开发5958 次安装1 天前更新
代码仓库

关于 blueprint-feature-tracker-sync

blueprint-feature-tracker-sync 用于协调项目功能跟踪器与 TODO.md,并更新进度信息。它支持只读摘要、差异处理,以及从 taskwarrior sidecar 转移已完成任务。

主要功能

  1. 01同步跟踪器与 TODO.md
  2. 02生成只读进度摘要
  3. 03转移已完成的任务项
  4. 04重新计算功能统计
  5. 05更新跟踪器和任务注册表

适用场景

  1. 01同步 TODO 复选框与功能状态
  2. 02不修改文件地汇总项目进度
  3. 03关闭 sidecar 中已完成任务
  4. 04刷新完成度统计

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/laurigates/claude-plugins --skill blueprint-feature-tracker-sync

安装后在 Claude Code 中输入/blueprint-feature-tracker-sync确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

REFERENCE.md
scripts/
blueprint-feature-tracker-sync.sh
scripts/tests/
test-blueprint-feature-tracker-sync.sh

详细介绍

将功能跟踪器 JSON 与 TODO.md 同步,并管理任务进度。

何时使用此技能

在以下情况下使用此技能……在以下情况下改用 blueprint-feature-tracker-status……
你要核对 TODO.md 中的复选框与跟踪器你只想查看完成情况统计
你要从 taskwarrior sidecar 中清空 WO 条目(--drain-wave)你想查看 PRD 覆盖情况或待开始任务列表
你要在完成工作后重新计算完成情况统计对于低级别的 FR 代码编辑,请改用 feature-tracking
你想通过 --summary 生成 Markdown 进度摘要你只需快速了解当前进度,且不需要写入文件

注意:从 v1.1.0 起,feature-tracker.json 是进度跟踪的唯一真实来源。tasks 部分取代了 work-overview.md。

用法:/blueprint:feature-tracker-sync [--summary] [--drain-wave WO-A,WO-B,...] [--evidence-files <list>] [--evidence <text>]

标志:

标志说明
--summary生成便于阅读的 Markdown 摘要(仅输出到 stdout,不写入文件)
--drain-wave WO-A,WO-B,...Sidecar 模式:将 tasks.pending 中逗号分隔列表里的已完成 WO 清空到 tasks.completed,然后将 implementing_wos 中的 WO 均已关闭的 FR 标记为完成
--evidence-files <list>逗号分隔的文件列表(每个 WO 对应一个文件),用于存放 --drain-wave 的证据字符串。按位置与 WO 列表配对
--evidence <text>内联证据字符串(仅适用于单个 WO)。文本较短且不含单引号时使用

交互模式

在任何结束时的 AskUserQuestion 菜单之前,先解析自动化配置:

bash "${CLAUDE_SKILL_DIR}/../../scripts/get-automation-config.sh"

当 EFFECTIVE_INTERACTION_MODE=quiet 且本次调用由自动化触发(autopilot、session bookend、drift-nudge 后续调用,而非用户输入的斜杠命令)时,跳过结束导航菜单(例如“接下来做什么?”/“再创建一个?”),采用安全默认操作,并以一行回执结束。安静模式绝不会跳过保护写入操作的确认关卡——它只会跳过导航菜单。用户直接调用时始终采用完整交互模式(明确意图优先于安静模式;参见 ADR-0020)。

模式选择(首先执行)

在开始任何工作之前,先判断适用的模式:

  1. 如果存在 --summary,则运行 模式:生成摘要 并退出。
  2. 如果存在 --drain-wave,则运行 模式:Taskwarrior Sidecar 清空 并退出。
  3. 否则,执行 sidecar 检测(下方步骤 0)。如果检测到 sidecar 且 TODO.md 不存在,则在面向用户的完成提示中优先采用 Sidecar 清空 语义;否则运行 模式:完整同步(默认)。

模式:生成摘要(--summary)

提供 --summary 时,生成便于阅读的进度报告,不修改任何文件:

jq -r '
  "# Work Overview: \(.project)\n\n" +
  "## Current Phase: \(.current_phase // "Not set")\n\n" +
  "**Progress**: \(.statistics.complete)/\(.statistics.total_features) features (\(.statistics.completion_percentage)%)\n\n" +
  "### In Progress\n" +
  (if (.tasks.in_progress | length) == 0 then "- (none)\n" else (.tasks.in_progress | map("- \(.description) [\(.id)]") | join("\n")) + "\n" end) +
  "\n### Pending\n" +
  (if (.tasks.pending | length) == 0 then "- (none)\n" else (.tasks.pending | map("- \(.description) [\(.id)]") | join("\n")) + "\n" end) +
  "\n### Recently Completed\n" +
  (if (.tasks.completed | length) == 0 then "- (none)\n" else (.tasks.completed | map("- \(.description) [\(.id)]") | join("\n")) + "\n" end) +
  "\n## Phase Status\n" +
  (.phases | map("- \(.name): \(.status)") | join("\n"))
' docs/blueprint/feature-tracker.json

输出示例:

# Work Overview: my-project

## Current Phase: phase-1

**Progress**: 22/42 features (52.4%)

### In Progress
- Implement OAuth integration [FR2.3]
- Add rate limiting [FR3.1]

### Pending
- Webhook support [FR4.1]
- Admin dashboard [FR5.1]

### Recently Completed
- User authentication [FR2.1]
- Session management [FR2.2]

## Phase Status
- Foundation: complete
- Core Features: in_progress
- Advanced Features: not_started

显示摘要后退出。

模式:完整同步(默认)

Step 0: 运行确定性核心

运行辅助程序。它负责机械化核心工作:检测 taskwarrior-sidecar 标记(SIDECAR=)、检查追踪器是否存在及有效、回填实现证据(文件是否存在 + 使用 git log 对提交去重)、通过固定决策表推断状态,并应用不可降级保护(EVIDENCE_FLIPPED=、status_inferred 问题),以及汇总统计数据(STAT_*、COMPLETION_PERCENTAGE=)。它会原地写入回填后的追踪器:

bash "${CLAUDE_SKILL_DIR}/scripts/blueprint-feature-tracker-sync.sh" --home-dir "$HOME" --project-dir "$(pwd)"

从输出中解析 STATUS= 和 ISSUES:。STATUS=ERROR 表示追踪器缺失(tracker_missing → 报告“未启用功能追踪;请运行 /blueprint:init”)或 JSON 无效。SIDECAR=true 表示正在使用 taskwarrior-sidecar 约定——还要通过可安全并行执行的 export | jq 习惯用法,探查是否存在实时的 taskwarrior 关联(是否有任何任务的 bpid 与项目蓝图 ID 匹配)(task bpid.any: status:any export | jq 'length',绝不要用 task list;参见 .claude/rules/parallel-safe-queries.md)。如果正在使用 sidecar,请跳过 TODO.md 核对步骤(步骤 4–5、8)——不存在权威的 TODO 文件——并将任何 WO 关闭操作转交给 Mode: Taskwarrior Sidecar Drain。

每个 status_inferred 问题都表示证据将某项功能的状态从 not_started 向上调整(保护机制绝不会降低更高的状态);请在步骤 9 报告的“根据证据推断”部分列出这些问题。有关规范的合并 jq 和测试证据模式,请参阅 REFERENCE.md。

Step 4: 检测差异

查找不一致之处:

  • 追踪器中标记为 complete 的功能,在 TODO.md 中却未勾选
  • TODO.md 中已勾选的功能,在追踪器中却未标记为 complete
  • tasks.in_progress 中的功能,在追踪器中却标记为 complete
  • PRD 状态与功能实现状态不符
  • 标记为 not_started 的功能,但步骤 3b 推断有已发布代码(通过步骤 5 确认)
Step 5: 询问用户如何处理差异

如果发现差异(使用 AskUserQuestion):

question: "Found {N} discrepancies. How should they be resolved?"
options:
  - label: "Update tracker from TODO.md"
    description: "Trust TODO.md, update tracker to match"
  - label: "Update TODO.md from tracker"
    description: "Trust the tracker, update TODO.md to match"
  - label: "Review each discrepancy"
    description: "Show each discrepancy and decide individually"
  - label: "Skip - don't resolve discrepancies"
    description: "Report discrepancies but don't change anything"
Step 6: 重新计算统计数据

功能级别的计数和完成百分比已包含在步骤 0 脚本输出中(STAT_COMPLETE/STAT_PARTIAL/STAT_IN_PROGRESS/STAT_NOT_STARTED/STAT_BLOCKED、COMPLETION_PERCENTAGE)。如果步骤 5 中解决差异后有状态发生变化,则根据所包含的功能重新推导阶段状态:

  • 如果所有功能均已完成,则为 complete
  • 如果任何功能处于 in_progress,则为 in_progress
  • 如果部分功能已完成、部分未完成,则为 partial
  • 如果没有任何功能已开始,则为 not_started
步骤 6a:解析项目组合链接(v3.3.0+,仅限根蓝图)

仅当根目录中的清单满足 workspaces.role == "root",且 feature-tracker 至少包含一个 implemented_by 数组非空的功能时运行。

  1. 对于每个包含 implemented_by 的功能:

    • 对每个 {workspace, ref} 条目,读取 <workspace>/docs/blueprint/feature-tracker.json 并查找 ref。

    • 收集子项状态。如果任何条目无法解析(文件缺失或 ref 缺失),记录一条警告,并在汇总时将该条目视为 not_started。

    • 使用以下规则推导根功能的 status:

      观察到的子项状态推导出的状态
      所有已解析条目均为 completecomplete
      任意条目为 blockedblocked
      任意条目为 in_progress,或 complete/not_started 混合出现partial
      所有条目均为 not_startednot_started
    • 将功能的 status 覆盖为推导出的值。不要修改项目组合功能上的 implementation;只重新计算状态。

  2. 通过读取每个子项的 statistics 块,重建顶层的 workspaces 摘要:

    "workspaces": {
      "projects/esp32-lamp": {
        "total": 14, "complete": 6, "completion_percentage": 42.9,
        "current_phase": "phase-1", "last_synced_at": "<now>"
      }
    }
    
  3. 应用推导出的状态后,重新计算根目录的 statistics,使项目组合级别的总数 反映由子项驱动的状态。

  4. 在同步报告(步骤 9)中,对无法解析的 implemented_by 条目发出警告;如果被引用的工作区不在根清单的 workspaces.children 中, 建议使用 /blueprint:workspace-scan。

步骤 7:更新 feature-tracker.json
  • 应用已解决的差异
  • 更新 statistics 部分
  • 将 last_updated 更新为今天的日期
  • 如果功能发生变化,则更新 PRD 状态
  • 将 current_phase 更新为第一个未完成的阶段
步骤 8:更新 TODO.md(如果存在)
  • 确保复选框状态与功能状态一致
  • 对于 complete 功能,使用 [x]
  • 对于 not_started 功能,使用 [ ]
  • 如有需要,在任务文本中注明部分完成情况
步骤 9:输出同步报告

打印:统计信息块(total/complete/partial/in_progress/not_started/blocked + 完成百分比)、当前阶段、阶段状态列表、活动任务列表、 “所做更改”(状态切换、修改过的 TODO 复选框)、“根据证据推断”(步骤 3b 中的切换及其提交 SHA),以及“未解决的差异”(如有跳过的项)。完整报告模板请参阅 REFERENCE.md。

步骤 10:更新任务注册表

更新 docs/blueprint/manifest.json 中的任务注册表条目:

jq --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --arg todo_hash "$(sha256sum TODO.md 2>/dev/null | cut -d' ' -f1)" \
  --argjson processed "${FEATURES_SYNCED:-0}" \
  '.task_registry["feature-tracker-sync"].last_completed_at = $now |
   .task_registry["feature-tracker-sync"].last_result = "success" |
   .task_registry["feature-tracker-sync"].context.last_todo_hash = $todo_hash |
   .task_registry["feature-tracker-sync"].stats.runs_total = ((.task_registry["feature-tracker-sync"].stats.runs_total // 0) + 1) |
   .task_registry["feature-tracker-sync"].stats.items_processed = $processed' \
  docs/blueprint/manifest.json > tmp.json && mv tmp.json docs/blueprint/manifest.json
步骤 11:提示下一步操作

使用 AskUserQuestion:

question: "Sync complete. What would you like to do next?"
options:
  - label: "View detailed status"
    description: "Run /blueprint:feature-tracker-status for full breakdown"
  - label: "Continue development"
    description: "Run /project:continue to work on next task"
  - label: "I'm done"
    description: "Exit sync"

模式:Taskwarrior 旁路任务清理(--drain-wave)

将一个或多个已完成的 WO 从 tasks.pending 清理至 tasks.completed,证据来源为 Taskwarrior 注释(或指定文件/ 内联字符串),然后切换其实现 WO 均已关闭的任何 FR 级条目。

步骤 1:解析波次列表

按逗号拆分 --drain-wave。对于每个 WO ID,按以下优先顺序匹配相应的证据 来源:

  1. --evidence-files 中对应位置的条目(文件路径),使用 jq --rawfile 读取,以避免单引号冲突。
  2. --evidence(仅限单 WO 清理)。
  3. 链接的 Taskwarrior 任务中最新的 annotate 行(步骤 2)。
  4. 最后,如果以上方式均不可用,则使用 AskUserQuestion 提示用户提供证据。

如果同时提供了 WO 列表和 --evidence-files 列表,但两者长度不一致, 则明确说明原因并拒绝运行——部分清理比不清理更糟糕。

步骤 2:从 taskwarrior 获取证据

对于此波次中的每个 WO,获取最新注释。使用支持并行的 export | jq 惯用写法——绝不要使用 task list——这样在任务不存在时会返回 退出码 0,不会取消同级工具调用(参见 .claude/rules/parallel-safe-queries.md):

task bpid:"$WO" status:completed export \
  | jq -r '.[0].annotations | sort_by(.entry) | last | .description // empty'

如果结果为空,则回退到 status:any(用户可能在排空前关闭了 任务)。如果仍为空,则回退到步骤 1 中的下一个优先级来源。

将每条证据字符串保存到临时文件(mktemp)中——提交消息中嵌入的单引号会与内联到 jq 程序字面量中的内容冲突,而 --rawfile 是标准的转义方式:

ev_file="$(mktemp)"
printf '%s' "$EVIDENCE_STRING" > "$ev_file"
步骤 3:将待处理项排空至已完成

对于此波次中的每个 WO-NNN,使用其证据文件 $ev_file,通过每个 WO 一次 jq 处理来推进跟踪器。将日期存储一次并作为参数传入,以便每个条目都写入相同的值:

today="$(date -u +%Y-%m-%d)"
jq --arg id "$WO" \
   --arg today "$today" \
   --rawfile ev "$ev_file" '
  .tasks.completed = (
    [ .tasks.pending[]
      | select(.id == $id)
      | . + {"completed": $today, "evidence": $ev}
    ] + .tasks.completed
  )
  | .tasks.pending = [.tasks.pending[] | select(.id != $id)]
' docs/blueprint/feature-tracker.json > docs/blueprint/feature-tracker.json.tmp
mv docs/blueprint/feature-tracker.json.tmp docs/blueprint/feature-tracker.json

按顺序循环处理 WOs——每次处理都读取上一次写入的文件——这样并发写入就不会在同一个文件上发生冲突。

如果某个 WO ID 不在 tasks.pending 中,则为该条目报告 skipped: not pending, 然后继续。不要因此报错并中止整个波次。

步骤 4:当所有实现中的 WO 均已关闭时,切换 FR 状态

对于 implementing_wos 数组与已排空波次重叠的每项功能,重新计算其 status。该切换是用户每个波次都会重复使用的第二种手动 jq 模式;在此处一次完成:

jq --arg today "$today" '
  (.features // [])
  |= map(
    if (.implementing_wos // []) | length > 0 then
      . as $fr
      | (.implementing_wos
         | map(. as $woid
               | (($fr | .. | objects | select(has("id")) | select(.id == $woid))
                  // null)
               | . != null)) as $resolved
      | (((.implementing_wos | length) > 0)
         and ([.implementing_wos[] as $wo
                | any(($fr.parent_tracker.tasks.completed // [])[]; .id == $wo)]
              | all)) as $all_done
      | if $all_done and (.status // "") != "complete"
        then . + {"status": "complete", "completed_at": $today}
        else .
        end
    else .
    end
  )
' docs/blueprint/feature-tracker.json > docs/blueprint/feature-tracker.json.tmp
mv docs/blueprint/feature-tracker.json.tmp docs/blueprint/feature-tracker.json

如果跟踪器架构将功能存储在扁平的 features 数组中,但形状不同(例如嵌套在 phases[].features[] 下),请调整路径前缀,同时保留相同逻辑:仅当 implementing_wos 中列出的所有 WO ID 都出现在 tasks.completed 中时,功能才会切换为 complete。

在运行报告(步骤 6)中记录每次切换。绝不要静默地将已处于 complete 状态的 FR 降级。

步骤 5:重新计算统计信息

重新运行**模式:完整同步(默认)**中的步骤 6,使总数反映已排空的 WOs 以及任何已切换的 FR。然后按照完整同步的步骤 7 更新 last_updated 和 current_phase。

步骤 6:报告

打印排空报告:

Sidecar Drain Report
====================
Wave: WO-031, WO-032, WO-033
Drained:
- WO-031: pending -> completed  (evidence: 142 chars from tw annotation)
- WO-032: pending -> completed  (evidence: 209 chars from /tmp/wo032_ev.txt)
- WO-033: skipped (not in tasks.pending)

FR flips:
- FR-017 (Skill Progression): in_progress -> complete

Statistics:
- Total Features: 42
- Complete: 23 (54.8%)  [+1 from FR-017]
- Recently Completed: WO-031, WO-032 added to top of tasks.completed

Next: run /taskwarrior:task-done if any sibling tasks should also close.

使用 rm -f "$ev_file" 清理临时证据文件。

单个 WO 简短形式

对于常见的单个 WO 情况,使用 --drain-wave WO-031,并搭配 --evidence "<text>" 或不带证据标志(自动从注释获取证据),整个流程比传统的手写 jq 单行命令更简短——并且生成相同的磁盘数据结构。如果还需要关闭关联的 taskwarrior 任务,请优先使用 /taskwarrior:task-done;此技能仅会编辑跟踪器。


直接编辑与示例输出

如需临时修改跟踪器(用于向 in_progress 添加内容、完成任务、将工作加入待处理队列的 jq 配方)以及示例摘要报告,请参阅 REFERENCE.md。

相关内容

  • taskwarrior-plugin:task-done — 关闭单个 taskwarrior 任务并排空关联的跟踪器条目;适用于一次有多个 WO 完成的波次,与此技能的 --drain-wave 搭配使用。
  • taskwarrior-plugin:task-coordinate — 在开始一个波次前列出接下来 N 个无阻塞任务,使你最终在此处排空的 WOs 与队列实际安排的内容一致。
  • session-plugin:session-end — 会话收尾协调器在调查发现已关闭且关联 WO(bpid)的 taskwarrior 任务仍留在跟踪器的 tasks.pending 中时,会提供 --drain-wave 处理,以便在会话结束时排空,而不是一直搁置,直到有人想起来手动运行此同步。
  • .claude/rules/parallel-safe-queries.md — 此技能查询 taskwarrior 时,必须使用 task ... export | jq 惯用写法。task list 在结果为空时会以退出码 1 结束,并静默取消同级并行工具调用。

评论

支持 Markdown