@plot-pm/board 0.4.0-rc.15 → 0.4.0-rc.150

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.4.0-rc.15",
3
+ "version": "0.4.0-rc.150",
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-config.sh CHANGED
@@ -26,7 +26,20 @@
26
26
  # Known keys (see the plot skill's Setup section):
27
27
  # Project board | Branch prefixes | Plan directory | Active index |
28
28
  # Delivered index | Sprint directory | Story directory | Story index |
29
- # Plan template | Main branch
29
+ # Plan template | Main branch | Board command
30
+ # Agent-runner keys (optional; Plot hardcodes no agent tooling, Principle 5):
31
+ # Worker command how /plot-dispatch runs an agent headless on a worktree.
32
+ # `none` = asked, and this repo starts workers by hand —
33
+ # a DELIBERATE absence, distinct from a missing key so
34
+ # /plot-dispatch stops asking at every fan-out. Never run
35
+ # as a command. Absent = nobody has been asked yet, and
36
+ # the first dispatch asks (never /plot-init: at adoption
37
+ # the question meets a need the answerer does not have,
38
+ # gets a shrug, and an answered-and-wrong key is harder
39
+ # to fix than a missing one).
40
+ # Approve command how the board runs `/plot-approve <slug>`; the prompt is
41
+ # appended as one argument. Absent = the board's Approve
42
+ # button renders disabled, naming this key as the fix.
30
43
  # Plot 2 posture keys (repo-declared ceremony bounds; all optional):
31
44
  # Plan PRs required | never | optional (never = hard gate)
32
45
  # Implementation home this repo | <repo/path list> | none
package/plot-plan-meta.sh CHANGED
@@ -96,6 +96,16 @@
96
96
  # Exception to "front matter wins": started is ADDITIVE —
97
97
  # canonical entries and the front-matter entry merge
98
98
  # (canonical first, front matter appended)
99
+ # rounds how many rounds of /plot:challenge-the-plan the plan has been
100
+ # through, read from the `CHALLENGE-THE-PLAN-METADATA` block
101
+ # the skill writes. **OMITTED ENTIRELY when the plan carries no
102
+ # such block** — absent is not zero. A plan nobody has
103
+ # interrogated and a plan interrogated to no effect want
104
+ # opposite reactions from a reader, so the field is missing
105
+ # rather than 0, the same rule `claimed`/`eligible` follow on
106
+ # the board side. A malformed or truncated block is reported
107
+ # the same way: the round is simply absent, and every other
108
+ # field still parses.
99
109
  #
100
110
  # title/sprint/story/assignee are the board-facing surface (`@plot-pm/board`
101
111
  # consumes this script instead of parsing plans itself). Front matter wins over
@@ -201,7 +211,11 @@ function reset_state() {
201
211
  canon_review = ""; canon_impl = ""; canon_approved = ""; canon_released = ""
202
212
  canon_delivered = ""
203
213
  h1_title = ""
204
- in_fm = 0; section = ""; in_comment = 0; branches_seen = 0
214
+ # "" means the plan carries no readable round NOT zero. Emitted by omitting
215
+ # the field, so a consumer cannot mistake "never interrogated" for "asked
216
+ # nothing".
217
+ rounds = ""
218
+ in_fm = 0; section = ""; in_comment = 0; in_challenge = 0; branches_seen = 0
205
219
  delete branches; n_branches = 0
206
220
  delete prs; n_prs = 0
207
221
  delete wave_names; delete wave_of; delete wave_seq; delete wave_count
@@ -279,7 +293,10 @@ function emit_record( fmt, praw, palt_raw, traw, title, sprint, story, assigne
279
293
  out = out ",\"delivered_raw\":\"" jesc(delivered) "\""
280
294
  out = out ",\"started_raw\":["
281
295
  for (i = 1; i <= n_started; i++) out = out (i > 1 ? "," : "") "\"" jesc(started[i]) "\""
282
- out = out "]}"
296
+ out = out "]"
297
+ # OMITTED, not zeroed, when no block was found. The absence is the message.
298
+ if (rounds != "") out = out ",\"rounds\":" rounds
299
+ out = out "}"
283
300
  print out
284
301
  }
285
302
  BEGIN { branch_re = "`(" PREFIXES ")/[^`]+`" }
@@ -309,8 +326,31 @@ in_fm {
309
326
  }
310
327
  # Interior of multi-line HTML comments is non-content (template guidance
311
328
  # blocks); single-line "<!-- ... -->" placeholders are unaffected.
312
- in_comment { if ($0 ~ /-->/) in_comment = 0; next }
313
- /<!--/ && $0 !~ /-->/ { in_comment = 1; next }
329
+ #
330
+ # ONE exception, and it is deliberately keyed on a sentinel rather than on
331
+ # "comments that look like JSON": /plot:challenge-the-plan writes its state into
332
+ # the plan as `<!-- CHALLENGE-THE-PLAN-METADATA … END-… -->`, and the round it
333
+ # records is the only thing in there this parser reports. Everything else in the
334
+ # block (question history, category coverage) stays non-content — the script
335
+ # collects, the skill interprets.
336
+ in_comment {
337
+ if (in_challenge && rounds == "" && $0 ~ /^[ \t]*"round"[ \t]*:[ \t]*[0-9]+/) {
338
+ _r = $0
339
+ sub(/^[ \t]*"round"[ \t]*:[ \t]*/, "", _r)
340
+ sub(/[^0-9].*$/, "", _r)
341
+ if (_r != "") rounds = _r + 0
342
+ }
343
+ if ($0 ~ /-->/) { in_comment = 0; in_challenge = 0 }
344
+ next
345
+ }
346
+ /<!--/ && $0 !~ /-->/ {
347
+ in_comment = 1
348
+ # A truncated block never closes; it simply runs to EOF as a comment, and the
349
+ # round stays whatever was read before the truncation — absent if the "round"
350
+ # line was itself lost. Nothing else in the record is affected either way.
351
+ in_challenge = ($0 ~ /CHALLENGE-THE-PLAN-METADATA/) ? 1 : 0
352
+ next
353
+ }
314
354
  # First H1 is the title fallback (front matter title: still wins in emit).
315
355
  /^#[ \t]/ && h1_title == "" { h1_title = trim(substr($0, 2)) }
316
356
  /^## / {