Run the script. It does the whole job — scan, analyse, render.
python3 skills/project/tracking-progress/scripts/tracking_progress.py
It writes .scratch/progress.html and prints the path. Single self-contained file: no network, no dependencies, opens from file:// (a flowchart-only mermaid build, scripts/mermaid.flow.min.js, is inlined — the page weighs about 1 MB). Page renders dark by default; the 亮色 button (top-right) switches to light and the choice is remembered via localStorage. Pass a repo root as the first argument to scan a different project.
The page includes per-spec dependency diagrams (mermaid, colours follow the theme), and every spec name / ticket id has a copy-icon button next to it — ticket ids copy as spec#id. The spec name itself is inert (clicking it does nothing). The wayfinder 地图 / spec badge next to it is the link: clicking opens the source map.md / spec.md in a new tab. Ticket-title links open in a new tab too.
Then:
- Open the HTML:
open .scratch/progress.html. - Report the headline (the page leads with a one-sentence conclusion) and the 现在能开工的 table. Link the HTML as
[任务进度](.scratch/progress.html). - Open the page's 未能识别的文件 section if it is non-empty. For each file, decide whether it actually holds tasks. If any does, the script is missing a convention — ask the user whether to file an issue at
.scratch/tracking-progress/issues/describing the unrecognised format, then add the rule to the script. (The script prints only the output path; the count, if any, lives on the page.)
What it recognises
| Where tasks live | How status is read |
|---|---|
<spec>/issues/NN-slug.md, <spec>/impl/NN-slug.md, <spec>/NN-slug.md |
Status: / 状态: line, bare or bold |
issues/open/ vs issues/done/ |
the directory name |
ticket file with Blocked by: but no status |
open (nobody marked it done) |
memory.md checkpoint rows |
- [x] done, - [ ] open, - [~] in progress |
wayfinder map.md + its children |
Status: claimed / resolved, Blocked by: NN |
memory/ and the top-level research/ are never scanned — they are history, not work in flight. A spec-level <spec>/research/*.md is listed under its spec with links (new tab), status-free.
Status strings are matched loosely: resolved / done / 已完成 / 定稿 all count as done, claimed / in-progress / 进行中 as in progress, everything else as open.
What the page says (and how to read odd bits)
- Blocking only counts ids that exist. A
Blocked by:referencing a number no ticket owns (often a document reference likeADR-0046minted into an id) is shown as a dangling ref, not treated as a blocker. - 互相阻塞的票 (A blocks B, B blocks A) are drawn with dashed amber edges in the wave diagram — someone has to break the loop by hand.
- 未建票 vs 票已建齐: a map/checklist row with no ticket file behind it is marked 未建 (badge on the spec head, mark on the row, dashed node in the graph, count in the per-spec table). A spec where every row has a ticket file gets the 票已建齐 badge.
- 口径写在页面上: progress = done ÷ total, blockers in the denominator; one ticket = one ticket file or one
memory.mdchecklist row, so "done" can include process notes like 「写 spec.md」. The page states this instead of hiding it.