@plot-pm/board 0.6.0-rc.99 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plot-pm/board",
3
- "version": "0.6.0-rc.99",
3
+ "version": "0.6.0",
4
4
  "description": "Local Kanban board for Plot — a glanceable view of plan phases from docs/plans, with sprint and story filters",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/plot-plan-meta.sh CHANGED
@@ -72,6 +72,9 @@
72
72
  # `<!-- claimed: ... -->`) bind to the LINE carrying the
73
73
  # backticked branch name. An annotation on a wrapped
74
74
  # continuation line is not seen — keep it on the branch line.
75
+ # `<!-- deferred -->` (bare, no colon) sets the flag with no
76
+ # reason; `waves[].branches[].deferred_reason` carries the
77
+ # sentence after the colon, "" where none was written.
75
78
  # prs PR numbers from `→ #NNN` links in the `## Branches`
76
79
  # section (sorted, unique)
77
80
  # changelog the plan's `## Changelog` entries, one string per bullet, in
@@ -254,7 +257,7 @@ function reset_state() {
254
257
  fm_issue = ""; canon_issue = ""
255
258
  delete issues; n_issues = 0
256
259
  delete wave_names; delete wave_of; delete wave_seq; delete wave_count
257
- delete deferred_of; delete claimed_of; delete ordered_b; n_waves = 0
260
+ delete deferred_of; delete deferred_why; delete claimed_of; delete ordered_b; n_waves = 0
258
261
  delete started; n_started = 0
259
262
  fm_changelog = ""
260
263
  delete changelog; n_changelog = 0; changelog_seen = 0; cl_open = 0
@@ -350,6 +353,7 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
350
353
  for (i = 1; i <= n_branches; i++) {
351
354
  if (wave_of[i] != w) continue
352
355
  out = out (first ? "" : ",") "{\"branch\":\"" jesc(ordered_b[i]) "\",\"deferred\":" deferred_of[i] \
356
+ ",\"deferred_reason\":\"" jesc(deferred_why[i]) "\"" \
353
357
  ",\"claimed\":\"" jesc(claimed_of[i]) "\"}"
354
358
  first = 0
355
359
  }
@@ -526,6 +530,30 @@ section == "branches" {
526
530
  sub(/[ \t]*-->.*$/, "", _c)
527
531
  claim_note = trim(_c)
528
532
  }
533
+ # THE REASON FOR THE DEFERRAL, and not merely the fact of one.
534
+ #
535
+ # `<!-- deferred: verified already implemented 2026-08-17 — startRepair() at
536
+ # fleet.ts:806 -->` was tested for presence and the sentence after the colon
537
+ # was dropped on the floor. So the board could say `deferred` beside `no
538
+ # commits` and never say that the first is the REASON for the second — a
539
+ # reader with no access to the plan file saw a branch nobody started and no
540
+ # statement that nobody should.
541
+ #
542
+ # Extracted the same way and in the same place as the claim note, for the same
543
+ # reason: `match()` in the branch loop below clobbers RSTART/RLENGTH, so
544
+ # anything read from the whole line must be read before it runs.
545
+ #
546
+ # Newlines are already impossible here — awk hands this rule one line, and the
547
+ # documented contract is that an annotation binds to the line carrying the
548
+ # branch name. A deferral whose text is wrapped onto a continuation line is
549
+ # not seen, exactly as `deferred` itself was not.
550
+ defer_note = ""
551
+ if (index($0, "deferred:") > 0) {
552
+ _d = $0
553
+ sub(/^.*<!--[ \t]*deferred:[ \t]*/, "", _d)
554
+ sub(/[ \t]*-->.*$/, "", _d)
555
+ defer_note = trim(_d)
556
+ }
529
557
  line = $0
530
558
  while (match(line, branch_re)) {
531
559
  b = substr(line, RSTART + 1, RLENGTH - 2)
@@ -533,7 +561,19 @@ section == "branches" {
533
561
  if (n_waves == 0) { wave_names[++n_waves] = "" }
534
562
  wave_of[n_branches] = n_waves
535
563
  wave_seq[n_branches] = ++wave_count[n_waves]
536
- deferred_of[n_branches] = ($0 ~ /<!--[ \t]*deferred:/) ? "true" : "false"
564
+ # THE FLAG accepts the bare form as well as the annotated one.
565
+ #
566
+ # It matched `deferred:` only, so `<!-- deferred -->` — the annotation with
567
+ # nothing after it — read as NOT deferred at all: the strongest statement a
568
+ # plan can make about a branch, dropped for want of a colon. A reader
569
+ # writing the shorter form has said the branch will not be built; the
570
+ # parser now hears it.
571
+ deferred_of[n_branches] = ($0 ~ /<!--[ \t]*deferred[ \t]*(:|-->)/) ? "true" : "false"
572
+ # The reason travels with the flag. Empty on every non-deferred branch, and
573
+ # empty is also the honest answer for the bare form: the branch IS deferred
574
+ # and no reason was recorded, which is a different statement from a reason
575
+ # of "".
576
+ deferred_why[n_branches] = defer_note
537
577
  # Claim reflection, written by the worker after its ref push succeeds. This
538
578
  # is a reflection, not the claim: git refs remain authoritative.
539
579
  claimed_of[n_branches] = claim_note