@plot-pm/board 0.8.0 → 0.8.1-rc.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.8.0",
3
+ "version": "0.8.1-rc.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
@@ -181,15 +181,18 @@
181
181
  # canonical entries and the front-matter entry merge
182
182
  # (canonical first, front matter appended)
183
183
  # rounds how many rounds of /plot:challenge-the-plan the plan has been
184
- # through, read from the `CHALLENGE-THE-PLAN-METADATA` block
185
- # the skill writes. **OMITTED ENTIRELY when the plan carries no
186
- # such block** absent is not zero. A plan nobody has
187
- # interrogated and a plan interrogated to no effect want
188
- # opposite reactions from a reader, so the field is missing
189
- # rather than 0, the same rule `claimed`/`eligible` follow on
190
- # the board side. A malformed or truncated block is reported
191
- # the same way: the round is simply absent, and every other
192
- # field still parses.
184
+ # through, read from `## Status` `Rounds:` first, YAML front
185
+ # matter `rounds:` second, and the `CHALLENGE-THE-PLAN-METADATA`
186
+ # block last. The field wins a disagreement (the file states
187
+ # what the reader sees), and the block remains readable so the
188
+ # 40 plans carrying only a block go on reporting correctly.
189
+ # **OMITTED ENTIRELY when no source carries a readable round**
190
+ # absent is not zero. A plan nobody has interrogated and a
191
+ # plan interrogated to no effect want opposite reactions from a
192
+ # reader, so the field is missing rather than 0, the same rule
193
+ # `claimed`/`eligible` follow on the board side. A malformed or
194
+ # truncated block is reported the same way: the round is simply
195
+ # absent, and every other field still parses.
193
196
  #
194
197
  # title/sprint/story/assignee are the board-facing surface (`@plot-pm/board`
195
198
  # consumes this script instead of parsing plans itself). Front matter wins over
@@ -290,15 +293,17 @@ function reset_state() {
290
293
  fm_title = ""; fm_sprint = ""; fm_story = ""; fm_assignee = ""
291
294
  fm_review = ""; fm_impl = ""; fm_approved = ""; fm_started = ""; fm_released = ""
292
295
  fm_delivered = ""; fm_design = ""
296
+ fm_rounds = ""
293
297
  canon_phase = ""; canon_type = ""
294
298
  canon_sprint = ""; canon_story = ""; canon_assignee = ""
295
299
  canon_review = ""; canon_impl = ""; canon_approved = ""; canon_released = ""
296
300
  canon_delivered = ""; canon_design = ""
301
+ canon_rounds = ""
297
302
  h1_title = ""
298
303
  # "" means the plan carries no readable round — NOT zero. Emitted by omitting
299
304
  # the field, so a consumer cannot mistake "never interrogated" for "asked
300
305
  # nothing".
301
- rounds = ""
306
+ block_rounds = ""
302
307
  in_fm = 0; section = ""; in_comment = 0; in_challenge = 0; in_fence = 0; branches_seen = 0; waves_seen = 0
303
308
  delete branches; n_branches = 0
304
309
  delete prs; n_prs = 0
@@ -441,7 +446,14 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
441
446
  out = out ",\"started_raw\":["
442
447
  for (i = 1; i <= n_started; i++) out = out (i > 1 ? "," : "") "\"" jesc(started[i]) "\""
443
448
  out = out "]"
444
- # OMITTED, not zeroed, when no block was found. The absence is the message.
449
+ # Rounds: preference order: ## Status, front matter, CHALLENGE block fallback.
450
+ # A placeholder ("<!-- optional -->") counts as absent, like Sprint/Story.
451
+ # OMITTED, not zeroed, when no source carries a readable round.
452
+ rounds = ""
453
+ _r = strip_placeholder(canon_rounds)
454
+ if (_r == "") _r = strip_placeholder(fm_rounds)
455
+ if (_r == "") _r = block_rounds
456
+ if (_r != "" && _r ~ /^[0-9]+$/) rounds = _r + 0
445
457
  if (rounds != "") out = out ",\"rounds\":" rounds
446
458
  out = out "}"
447
459
  print out
@@ -480,6 +492,7 @@ in_fm {
480
492
  # here: front matter in this repo is a flat key/value surface, and guessing a
481
493
  # list grammar the format never promised would invent a contract.
482
494
  else if (lower ~ /^changelog:/ && fm_changelog == "") fm_changelog = val_after_colon($0)
495
+ else if (lower ~ /^rounds:/ && fm_rounds == "") fm_rounds = val_after_colon($0)
483
496
  next
484
497
  }
485
498
  # Interior of multi-line HTML comments is non-content (template guidance
@@ -492,11 +505,11 @@ in_fm {
492
505
  # block (question history, category coverage) stays non-content — the script
493
506
  # collects, the skill interprets.
494
507
  in_comment {
495
- if (in_challenge && rounds == "" && $0 ~ /^[ \t]*"round"[ \t]*:[ \t]*[0-9]+/) {
508
+ if (in_challenge && block_rounds == "" && $0 ~ /^[ \t]*"round"[ \t]*:[ \t]*[0-9]+/) {
496
509
  _r = $0
497
510
  sub(/^[ \t]*"round"[ \t]*:[ \t]*/, "", _r)
498
511
  sub(/[^0-9].*$/, "", _r)
499
- if (_r != "") rounds = _r + 0
512
+ if (_r != "") block_rounds = _r + 0
500
513
  }
501
514
  if ($0 ~ /-->/) { in_comment = 0; in_challenge = 0 }
502
515
  next
@@ -556,6 +569,7 @@ section == "status" {
556
569
  else if (lower ~ /^[ \t]*[-*]?[ \t]*\**review[:*]/ && canon_review == "") canon_review = val_after_colon($0)
557
570
  else if (lower ~ /^[ \t]*[-*]?[ \t]*\**impl[:*]/ && canon_impl == "") canon_impl = val_after_colon($0)
558
571
  else if (lower ~ /^[ \t]*[-*]?[ \t]*\**design[:*]/ && canon_design == "") canon_design = val_after_colon($0)
572
+ else if (lower ~ /^[ \t]*[-*]?[ \t]*\**rounds[:*]/ && canon_rounds == "") canon_rounds = val_after_colon($0)
559
573
  else if (lower ~ /^[ \t]*[-*]?[ \t]*\**approved[:*]/ && canon_approved == "") canon_approved = val_after_colon($0)
560
574
  else if (lower ~ /^[ \t]*[-*]?[ \t]*\**released[:*]/ && canon_released == "") canon_released = val_after_colon($0)
561
575
  else if (lower ~ /^[ \t]*[-*]?[ \t]*\**delivered[:*]/ && canon_delivered == "") canon_delivered = val_after_colon($0)