@nowline/cli 0.8.5 → 0.9.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.
Files changed (102) hide show
  1. package/README.md +42 -12
  2. package/dist/cli/args.d.ts +21 -5
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +26 -1
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/formats.d.ts.map +1 -1
  7. package/dist/cli/help.d.ts.map +1 -1
  8. package/dist/cli/help.js +35 -2
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/options.d.ts +74 -0
  11. package/dist/cli/options.d.ts.map +1 -0
  12. package/dist/cli/options.js +209 -0
  13. package/dist/cli/options.js.map +1 -0
  14. package/dist/commands/init.d.ts.map +1 -1
  15. package/dist/commands/init.js +2 -3
  16. package/dist/commands/init.js.map +1 -1
  17. package/dist/commands/mcp-install.d.ts +18 -0
  18. package/dist/commands/mcp-install.d.ts.map +1 -0
  19. package/dist/commands/mcp-install.js +151 -0
  20. package/dist/commands/mcp-install.js.map +1 -0
  21. package/dist/commands/mcp.d.ts.map +1 -1
  22. package/dist/commands/mcp.js +6 -12
  23. package/dist/commands/mcp.js.map +1 -1
  24. package/dist/commands/render.d.ts +7 -0
  25. package/dist/commands/render.d.ts.map +1 -1
  26. package/dist/commands/render.js +176 -152
  27. package/dist/commands/render.js.map +1 -1
  28. package/dist/commands/serve.d.ts.map +1 -1
  29. package/dist/commands/serve.js +87 -60
  30. package/dist/commands/serve.js.map +1 -1
  31. package/dist/core/parse.js.map +1 -1
  32. package/dist/diagnostics/adapt.d.ts +12 -1
  33. package/dist/diagnostics/adapt.d.ts.map +1 -1
  34. package/dist/diagnostics/adapt.js +53 -1
  35. package/dist/diagnostics/adapt.js.map +1 -1
  36. package/dist/diagnostics/format.js.map +1 -1
  37. package/dist/diagnostics/model.d.ts +1 -1
  38. package/dist/diagnostics/text.js.map +1 -1
  39. package/dist/generated/version.d.ts +1 -1
  40. package/dist/generated/version.js +2 -2
  41. package/dist/i18n/locale.d.ts +1 -1
  42. package/dist/i18n/locale.d.ts.map +1 -1
  43. package/dist/i18n/locale.js +2 -5
  44. package/dist/i18n/locale.js.map +1 -1
  45. package/dist/index.js +4 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/io/config.d.ts +1 -1
  48. package/dist/io/config.d.ts.map +1 -1
  49. package/dist/io/config.js +1 -1
  50. package/dist/io/config.js.map +1 -1
  51. package/dist/io/exit-codes.d.ts.map +1 -1
  52. package/dist/io/exit-codes.js.map +1 -1
  53. package/dist/io/log.d.ts +17 -0
  54. package/dist/io/log.d.ts.map +1 -0
  55. package/dist/io/log.js +16 -0
  56. package/dist/io/log.js.map +1 -0
  57. package/dist/io/read.d.ts +3 -0
  58. package/dist/io/read.d.ts.map +1 -1
  59. package/dist/io/read.js +32 -5
  60. package/dist/io/read.js.map +1 -1
  61. package/dist/io/write.js.map +1 -1
  62. package/dist/mcp-install/clients.d.ts +58 -0
  63. package/dist/mcp-install/clients.d.ts.map +1 -0
  64. package/dist/mcp-install/clients.js +304 -0
  65. package/dist/mcp-install/clients.js.map +1 -0
  66. package/dist/mcp-install/host.d.ts +29 -0
  67. package/dist/mcp-install/host.d.ts.map +1 -0
  68. package/dist/mcp-install/host.js +72 -0
  69. package/dist/mcp-install/host.js.map +1 -0
  70. package/dist/mcp-install/json-config.d.ts +29 -0
  71. package/dist/mcp-install/json-config.d.ts.map +1 -0
  72. package/dist/mcp-install/json-config.js +139 -0
  73. package/dist/mcp-install/json-config.js.map +1 -0
  74. package/dist/mcp-install/server-command.d.ts +26 -0
  75. package/dist/mcp-install/server-command.d.ts.map +1 -0
  76. package/dist/mcp-install/server-command.js +52 -0
  77. package/dist/mcp-install/server-command.js.map +1 -0
  78. package/man/fr/nowline.1 +246 -19
  79. package/man/fr/nowline.5 +819 -45
  80. package/man/nowline.1 +191 -18
  81. package/man/nowline.5 +764 -36
  82. package/package.json +24 -24
  83. package/src/cli/args.ts +69 -8
  84. package/src/cli/help.ts +35 -2
  85. package/src/cli/options.ts +286 -0
  86. package/src/commands/init.ts +2 -3
  87. package/src/commands/mcp-install.ts +211 -0
  88. package/src/commands/mcp.ts +9 -14
  89. package/src/commands/render.ts +219 -186
  90. package/src/commands/serve.ts +102 -74
  91. package/src/diagnostics/adapt.ts +62 -0
  92. package/src/diagnostics/model.ts +1 -1
  93. package/src/generated/version.ts +2 -2
  94. package/src/i18n/locale.ts +2 -6
  95. package/src/index.ts +3 -0
  96. package/src/io/config.ts +0 -1
  97. package/src/io/log.ts +33 -0
  98. package/src/io/read.ts +39 -5
  99. package/src/mcp-install/clients.ts +443 -0
  100. package/src/mcp-install/host.ts +106 -0
  101. package/src/mcp-install/json-config.ts +179 -0
  102. package/src/mcp-install/server-command.ts +75 -0
package/man/nowline.5 CHANGED
@@ -42,11 +42,11 @@ files.
42
42
  .It
43
43
  .Sy config
44
44
  section (optional). Rendering configuration: styles, defaults,
45
- scale, calendar, symbols.
45
+ scale, calendar, symbols, non-working and working days.
46
46
  .It
47
47
  .Sy roadmap
48
48
  section (required). Content: persons, teams, anchors, labels, sizes,
49
- statuses, swimlanes, items, milestones, footnotes.
49
+ statuses, waves, swimlanes, items, milestones, footnotes.
50
50
  .El
51
51
  .Pp
52
52
  .Sy config
@@ -163,14 +163,16 @@ The included file's
163
163
  .Sy style ,
164
164
  .Sy symbol ,
165
165
  .Sy default ,
166
+ .Sy calendar ,
167
+ .Sy non-working ,
166
168
  and
167
- .Sy calendar
169
+ .Sy working
168
170
  declarations.
169
171
  .It Sy Roadmap
170
172
  The included file's
171
173
  .Sy roadmap
172
174
  declaration plus all its content (persons, teams, anchors, labels,
173
- sizes, statuses, swimlanes, items, milestones, footnotes).
175
+ sizes, statuses, waves, swimlanes, items, milestones, footnotes).
174
176
  .El
175
177
  .Pp
176
178
  .Sy config:
@@ -182,6 +184,12 @@ On collision, the
182
184
  .Em parent wins
183
185
  and the parser emits a warning identifying the shadowed definition
184
186
  and source file.
187
+ A
188
+ .Sy non-working
189
+ or
190
+ .Sy working
191
+ declaration collides only with a parent declaration of the same keyword
192
+ and name; an unnamed one never collides and always merges.
185
193
  .It Sy ignore
186
194
  Child config is dropped entirely.
187
195
  If child roadmap content is merged, it resolves styles from the
@@ -258,6 +266,38 @@ line; this is an explicit exception to the
258
266
  merge behaviour because
259
267
  .Sy start:
260
268
  defines the shared timeline baseline.
269
+ .Pp
270
+ Waves never merge.
271
+ For any include whose
272
+ .Sy roadmap:
273
+ mode is not
274
+ .Sy ignore ,
275
+ if the child declares a
276
+ .Sy roadmap ,
277
+ has swimlanes, or declares waves, the parent and child must declare
278
+ the same waves: the same ids, in the same order, with the same
279
+ resolved start floors.
280
+ Floors are compared by the date they resolve to, so
281
+ .Sy after:fy-budget
282
+ and
283
+ .Sy after:2026-02-02
284
+ agree when the anchor is on that date.
285
+ A mismatch in either direction is the error
286
+ .Sy NL.E0202 ,
287
+ reported on the parent's
288
+ .Sy include
289
+ line; two files with no waves pass.
290
+ Waves are barriers across the whole canvas, so a silently shadowed
291
+ wave list would move every lane's columns.
292
+ When ids, order and floors agree, a differing title,
293
+ .Sy style: ,
294
+ .Sy labels: ,
295
+ .Sy link: ,
296
+ or description is the warning
297
+ .Sy NL.W0701
298
+ and the parent's definition is used.
299
+ A vocabulary-only child (persons, teams, labels, sizes, statuses,
300
+ anchors; no roadmap, no swimlanes, no waves) does not take part.
261
301
  .Sh CONFIG SECTION
262
302
  The optional
263
303
  .Sy config
@@ -265,14 +305,16 @@ section marker appears before
265
305
  .Sy roadmap .
266
306
  Config keywords sit at the top level (not indented under the
267
307
  marker) and define rendering vocabulary, defaults, axis settings,
268
- day arithmetic, and custom symbols.
308
+ day arithmetic, non-working days, and custom symbols.
269
309
  .Pp
270
- Five config keywords:
310
+ Seven config keywords:
271
311
  .Sy scale ,
272
312
  .Sy style ,
273
313
  .Sy symbol ,
274
314
  .Sy default ,
275
- .Sy calendar .
315
+ .Sy calendar ,
316
+ .Sy non-working ,
317
+ .Sy working .
276
318
  Every config entry is optional; if
277
319
  .Sy config
278
320
  is omitted, all built-in defaults apply.
@@ -370,6 +412,13 @@ Banned, by entity type:
370
412
  .Sy date , link , description .
371
413
  .It Sy default footnote
372
414
  .Sy on , link , description .
415
+ .It Sy every default line
416
+ .Sy wave
417
+ \(em sequencing creates invisible dependencies, and there is no
418
+ .Sy default wave .
419
+ In a roadmap with waves it is an error; in a roadmap without waves
420
+ it is ignored with the warning
421
+ .Sy NL.W0702 .
373
422
  .El
374
423
  .Pp
375
424
  Raw style properties
@@ -461,7 +510,7 @@ Engineering working-day arithmetic.
461
510
  Calendar-day arithmetic with weekends.
462
511
  .Sy days-per-week:7 ,
463
512
  .Sy days-per-month:30 ,
464
- .Sy days-per-quarter:90 ,
513
+ .Sy days-per-quarter:91 ,
465
514
  .Sy days-per-year:365 .
466
515
  .It Sy calendar:custom
467
516
  Author-supplied values via the
@@ -506,6 +555,166 @@ is
506
555
  .Sy 260d ,
507
556
  not
508
557
  .Sy 12 \(mu 22d = 264d .
558
+ .Ss non-working and working \(em declarations
559
+ A
560
+ .Sy non-working
561
+ declaration takes days out of the schedule: weekends, holidays,
562
+ closures.
563
+ A
564
+ .Sy working
565
+ declaration puts days back, for a crunch Saturday or a make-up day.
566
+ Both are config keywords and share one shape:
567
+ .Bd -literal -offset indent
568
+ config
569
+
570
+ non-working weekend "Weekend" every:[fri, sat]
571
+ non-working new-year "New Year's Day" date:2027-01-01
572
+ non-working summit "Company summit" start:2026-09-14 end:2026-09-16
573
+ non-working fridays every:fri start:2026-07-01 end:2026-08-31
574
+ working crunch "Crunch Saturday" date:2026-01-10
575
+ .Ed
576
+ .Pp
577
+ The id and the title are both optional.
578
+ Durations count working days only, so an item that spans a non-working
579
+ day ends later, and an item that spans a working exception ends
580
+ sooner.
581
+ The chart labels a dated declaration that has a title
582
+ .Po
583
+ .Sy date:
584
+ or
585
+ .Sy start:
586
+ with
587
+ .Sy end:
588
+ and no
589
+ .Sy every:
590
+ .Pc
591
+ with its title and the number of working days it removes, for example
592
+ .Dq Thanksgiving \[u00B7] 2d .
593
+ Under
594
+ .Sy hide
595
+ the label sits on a cut line at the seam, and under
596
+ .Sy show
597
+ at the left edge of the shaded band.
598
+ A dated
599
+ .Sy working
600
+ declaration with a title is labelled at the days it turns from
601
+ non-working to working, with its title and the number of days it adds,
602
+ for example
603
+ .Dq Crunch Saturday \[u00B7] +1d ,
604
+ and with no cut line in either view; a weekday make-up day inside a
605
+ dated closure counts.
606
+ A title on a recurrence is not drawn.
607
+ A declaration takes these properties:
608
+ .Bl -tag -width "every:"
609
+ .It Sy date:
610
+ One ISO date or a list of dates.
611
+ .It Sy start:
612
+ One ISO date, inclusive: the first day of a range, or the day a
613
+ recurrence begins.
614
+ .It Sy end:
615
+ One ISO date, inclusive: the last day of a range, or the day a
616
+ recurrence stops.
617
+ It must not be before
618
+ .Sy start: .
619
+ .It Sy every:
620
+ One weekday or a list of
621
+ .Sy sun , mon , tue , wed , thu , fri , sat .
622
+ A weekly recurrence.
623
+ .El
624
+ .Pp
625
+ A declaration is exactly one of three shapes:
626
+ .Sy date:
627
+ alone; a range of
628
+ .Sy start:
629
+ and
630
+ .Sy end:
631
+ without
632
+ .Sy every: ;
633
+ or
634
+ .Sy every:
635
+ with optional
636
+ .Sy start:
637
+ and
638
+ .Sy end:
639
+ bounds.
640
+ With neither bound a recurrence is open-ended and holds in every week.
641
+ .Pp
642
+ On a given day the most specific declaration decides, and
643
+ .Sy working
644
+ wins a tie:
645
+ .Bl -enum -offset indent -compact
646
+ .It
647
+ a dated declaration, a
648
+ .Sy date:
649
+ list or a range;
650
+ .It
651
+ a bounded recurrence;
652
+ .It
653
+ the open-ended week.
654
+ .El
655
+ .Pp
656
+ Order never matters: the same declarations in any order, in the file
657
+ or in includes, give the same schedule.
658
+ .Sy calendar:business
659
+ supplies a
660
+ .Sy non-working weekend
661
+ declaration for Saturday and Sunday.
662
+ A
663
+ .Sy non-working
664
+ declaration named
665
+ .Sy weekend
666
+ replaces it, for any preset, so a Friday and Saturday week needs no
667
+ custom calendar; any other name adds to the preset.
668
+ .Pp
669
+ The open-ended week must keep a working day, and
670
+ .Sy days-per-week
671
+ should agree with the weekdays it leaves working
672
+ .Pq see Sx VALIDATION .
673
+ A declaration whose value or shape is malformed is skipped when the
674
+ calendar is built.
675
+ Under
676
+ .Sy config:isolate
677
+ the child's declarations stay in its region and have no effect on the
678
+ chart yet: the region is laid out on the host's calendar.
679
+ The validator reads only its own file, so a declaration in an include
680
+ is not counted by the open-ended week checks.
681
+ .Ss non-working: \(em day display
682
+ Under
683
+ .Sy calendar:business
684
+ the weekend is non-working: durations count working days only, and the
685
+ chart either hides those days or draws them.
686
+ The display is a roadmap-only style key, set on the
687
+ .Sy default roadmap
688
+ line (raw style keys are not allowed on the
689
+ .Sy roadmap
690
+ line itself):
691
+ .Bd -literal -offset indent
692
+ config
693
+
694
+ default roadmap non-working:show
695
+ .Ed
696
+ .Bl -tag -width "show"
697
+ .It Sy hide Pq default
698
+ Non-working days take no width; each run collapses to a seam.
699
+ .It Sy show
700
+ Non-working days are drawn at full width and shaded.
701
+ A bar paints across a weekend but ends at the end of its last working day,
702
+ so the gap between chained bars shows.
703
+ .El
704
+ .Pp
705
+ The display never changes the schedule, so Mermaid, MS Project, and XLSX
706
+ output is the same in both views.
707
+ It can also be chosen at render time; the first of these wins: the
708
+ .Fl -non-working
709
+ option (or the equivalent option on another surface), the file's
710
+ .Sy default roadmap non-working:
711
+ key, then
712
+ .Sy hide .
713
+ Under
714
+ .Sy calendar:full
715
+ and
716
+ .Sy calendar:custom
717
+ there are no non-working days and the key has no effect.
509
718
  .Sh ROADMAP SECTION
510
719
  The
511
720
  .Sy roadmap
@@ -555,18 +764,33 @@ resolved relative to the
555
764
  .Pa .nowline
556
765
  file's directory.
557
766
  Forward slashes on all platforms; only local paths are accepted.
767
+ The logo draws left of the title inside the header card, vertically
768
+ centered, and is embedded in the output (SVG inline, raster as a
769
+ base64 data URI).
558
770
  Asset resolution happens at render time, not parse time \(em a file
559
771
  referencing a missing logo is still a valid document.
772
+ A missing, unsupported or unreadable logo is a warning and the chart
773
+ renders as if no logo were declared; under
774
+ .Fl -strict
775
+ it is an error.
560
776
  .It Sy logo-size:
561
777
  Size preset
562
778
  .Pq Sy xs | sm | md | lg | xl ,
563
779
  default
564
780
  .Sy md .
781
+ Sets the drawn logo height (18, 24, 36, 48 or 72 px); the width follows
782
+ the logo's own aspect ratio, so a larger or smaller source is scaled to
783
+ fill the same slot.
784
+ A logo wider than 160 px at that height scales down to fit.
785
+ A logo taller than the title and author grows the header card;
786
+ .Sy xl
787
+ also grows the 72 px band of
788
+ .Sy header-position:above .
565
789
  .El
566
790
  .Pp
567
- Twelve roadmap-section keywords:
791
+ Thirteen roadmap-section keywords:
568
792
  .Sy swimlane , item , parallel , group ,
569
- .Sy person , team , anchor , label , size , status , milestone ,
793
+ .Sy person , team , anchor , label , size , status , wave , milestone ,
570
794
  .Sy footnote .
571
795
  Each follows the universal
572
796
  .Sy [id] ["title"] [key:value...]
@@ -663,15 +887,25 @@ swimlane platform
663
887
  .Pp
664
888
  A
665
889
  .Sy group
666
- with
667
- .Sy style: ,
668
- .Sy labels: ,
669
- or other visual properties renders with a visible bounding box
670
- plus a small title chiclet.
890
+ is drawn above and around its items, never beside them: a header
891
+ (its title over a bracket spanning exactly its dates) over a body
892
+ shaded with its
893
+ .Sy bg ,
894
+ padded above and below.
895
+ .Sy style:
896
+ changes only the colours.
671
897
  A
898
+ .Sy parallel
899
+ is drawn the same way, its tracks stacked in its body.
900
+ In a roadmap with waves, a
672
901
  .Sy group
673
- with no styling is purely structural \(em it only governs
674
- sequencing and inner row growth, with no visible artifact.
902
+ with no title, no
903
+ .Sy style: ,
904
+ and no
905
+ .Sy labels:
906
+ that carries
907
+ .Sy wave:
908
+ draws nothing; it only assigns membership.
675
909
  .Ss anchor \(em named date on the timeline
676
910
  .Bd -literal -offset indent
677
911
  anchor kickoff date:2026-01-06
@@ -780,6 +1014,119 @@ overrides.
780
1014
  .Pp
781
1015
  .Sy status
782
1016
  declarations must precede any entity that references them.
1017
+ .Ss wave \(em barrier across every swimlane
1018
+ .Bd -literal -offset indent
1019
+ wave id ["title"] [after:anchor|milestone|date] \e
1020
+ [style:...] [labels:...] [link:...]
1021
+ .Ed
1022
+ .Pp
1023
+ A
1024
+ .Sy wave
1025
+ is a strict, sequential barrier that spans every swimlane:
1026
+ .Em no item in wave k+1 starts before every item in wave k has ended .
1027
+ A wave opens for every lane at the instant the previous wave's
1028
+ slowest member ends, so lanes that finish early wait at the boundary.
1029
+ Waves are declared once, in order, in the roadmap section, and
1030
+ declaration order is time order.
1031
+ Work joins a wave with the
1032
+ .Sy wave:
1033
+ property on an
1034
+ .Sy item ,
1035
+ .Sy group ,
1036
+ or
1037
+ .Sy parallel .
1038
+ .Bd -literal -offset indent
1039
+ wave discover "Discover"
1040
+ wave build "Build"
1041
+ wave launch "Launch" after:fy-budget
1042
+
1043
+ swimlane web "Web"
1044
+ item research "UX research" duration:2w wave:discover
1045
+ group wave:build
1046
+ item checkout "Checkout v2" duration:3w
1047
+ item a11y "Accessibility pass" duration:1w
1048
+ item launch-page "Launch page" duration:1w wave:launch
1049
+ swimlane ops "Ops"
1050
+ item on-call "On-call and KTLO" duration:10w
1051
+
1052
+ milestone beta "Beta" after:build
1053
+ .Ed
1054
+ .Pp
1055
+ A
1056
+ .Sy wave
1057
+ line accepts:
1058
+ .Bl -tag -width "style:"
1059
+ .It Sy id
1060
+ Required
1061
+ .Pq Sy NL.E1100 .
1062
+ Joins the single shared identifier namespace.
1063
+ .It Sy title
1064
+ Optional.
1065
+ The strip label; falls back to the id.
1066
+ .It Sy after:
1067
+ Optional start floor.
1068
+ The wave cannot open before the latest of its elements.
1069
+ Each element must be an anchor id, the id of a milestone that has
1070
+ .Sy date: ,
1071
+ or an ISO date (at most one date); any other kind of entity is
1072
+ .Sy NL.E1106 .
1073
+ A gap between one wave's end and the next wave's floor is allowed.
1074
+ .It Sy style:
1075
+ Wave colours: the style's
1076
+ .Sy bg
1077
+ opts the wave into a column tint,
1078
+ .Sy fg
1079
+ colours its boundary line,
1080
+ .Sy text
1081
+ its strip label, and
1082
+ .Sy border
1083
+ sets the boundary dash.
1084
+ .It Sy labels: , link: , description
1085
+ Carried in the model, JSON and XLSX export, and LSP hover; not painted.
1086
+ .El
1087
+ .Pp
1088
+ Keys not allowed on a
1089
+ .Sy wave :
1090
+ .Sy before: , date: , start: , length: , duration: , size: ,
1091
+ .Sy capacity: , remaining: , wave:
1092
+ .Pq Sy NL.E1105 .
1093
+ A wave's span comes from its items.
1094
+ To give a wave a deadline, add a dated milestone
1095
+ .Sy after:<wave> ;
1096
+ it turns red when the wave runs late.
1097
+ .Pp
1098
+ Items without an effective wave are
1099
+ .Em background work :
1100
+ on-call, support, ongoing maintenance.
1101
+ A barrier never holds background work back and its own end never
1102
+ extends a wave, but it still follows lane order and its own
1103
+ .Sy after: .
1104
+ Background work is drawn hatched.
1105
+ .Pp
1106
+ A wave id is a valid
1107
+ .Sy after: ,
1108
+ .Sy before: ,
1109
+ and
1110
+ .Sy on:
1111
+ target.
1112
+ .Sy after:<wave>
1113
+ starts no earlier than the end of that wave, and a floating
1114
+ .Sy milestone after:<wave>
1115
+ sits on the wave's closing boundary.
1116
+ .Sy before:<wave>
1117
+ should finish before the wave's start (soft, like every
1118
+ .Sy before: ) .
1119
+ .Sy on:<wave>
1120
+ attaches a footnote to the wave.
1121
+ Wave references draw no dependency arrow.
1122
+ .Pp
1123
+ A roadmap
1124
+ .Qq has waves
1125
+ when it declares at least one wave with a valid id.
1126
+ In a roadmap without waves every
1127
+ .Sy wave:
1128
+ key is ignored with the warning
1129
+ .Sy NL.W0702 .
783
1130
  .Ss milestone \(em achievement marker
784
1131
  .Bd -literal -offset indent
785
1132
  milestone v1-ga "v1 GA" date:2026-06-30
@@ -809,7 +1156,7 @@ footnote capacity-risk "Team capacity risk" on:[mobile, platform]
809
1156
  .Pp
810
1157
  .Sy on:
811
1158
  is required and references one or more identifiers (item,
812
- swimlane, anchor, milestone, person, team).
1159
+ swimlane, anchor, milestone, wave, person, team).
813
1160
  Use bracket notation for multiples:
814
1161
  .Sy on:[id1, id2] .
815
1162
  Footnotes are numbered sequentially by document order; a
@@ -871,7 +1218,7 @@ and the
871
1218
  sub-directive.
872
1219
  .Sh UNIVERSAL PROPERTIES
873
1220
  These properties are valid on every entity type: items, swimlanes,
874
- parallel blocks, groups, milestones, anchors, persons, teams,
1221
+ parallel blocks, groups, milestones, anchors, waves, persons, teams,
875
1222
  labels, sizes, statuses, footnotes.
876
1223
  .Bl -tag -width "description"
877
1224
  .It Sy labels:
@@ -908,7 +1255,8 @@ Raw style properties
908
1255
  .Sy bg , Sy fg , Sy text , Sy border , Sy icon , Sy shadow ,
909
1256
  .Sy font , Sy weight , Sy italic , Sy text-size , Sy padding ,
910
1257
  .Sy spacing , Sy header-height , Sy corner-radius , Sy bracket ,
911
- .Sy capacity-icon , Sy timeline-position , Sy minor-grid
1258
+ .Sy header-position , Sy capacity-icon , Sy timeline-position ,
1259
+ .Sy minor-grid , Sy non-working
912
1260
  .Pc
913
1261
  may only appear in
914
1262
  .Sy style
@@ -921,6 +1269,8 @@ lines \(em both of which live in
921
1269
  and
922
1270
  .Sy before
923
1271
  are also valid on swimlanes, parallel blocks, and groups.
1272
+ .Sy wave
1273
+ is also valid on parallel blocks and groups, but not on swimlanes.
924
1274
  The rest are item-only.
925
1275
  .Bl -tag -width "remaining"
926
1276
  .It Sy status:
@@ -945,12 +1295,30 @@ Identifier or bracketed list.
945
1295
  The entity starts after the referenced entity finishes.
946
1296
  .Sy after:[a, b]
947
1297
  starts after the latest finisher.
948
- Accepts item, milestone, anchor, parallel, or group ids.
1298
+ Accepts item, milestone, anchor, parallel, group, or wave ids.
949
1299
  .It Sy before:
950
1300
  Identifier or bracketed list.
951
1301
  The entity must finish before the referenced entity starts.
952
1302
  .Sy before:[a, b]
953
1303
  finishes before the earliest starter.
1304
+ .It Sy wave:
1305
+ Wave id.
1306
+ Exactly one declared
1307
+ .Sy wave
1308
+ .Pq Sy wave:build ;
1309
+ an item belongs to at most one wave.
1310
+ The effective wave of an item is its own value, else that of its
1311
+ nearest enclosing
1312
+ .Sy group
1313
+ or
1314
+ .Sy parallel
1315
+ that carries one; a swimlane never contributes.
1316
+ A descendant may repeat its container's value but not differ from it
1317
+ .Pq Sy NL.E1102 .
1318
+ A block without
1319
+ .Sy wave:
1320
+ may hold children in different waves.
1321
+ Only meaningful in a roadmap with waves.
954
1322
  .It Sy size:
955
1323
  Size alias.
956
1324
  .Sy size:l
@@ -1197,11 +1565,33 @@ Default varies by entity.
1197
1565
  .It Sy header-height
1198
1566
  .Sy none | xs | sm | md Pq default | lg | xl .
1199
1567
  Roadmap-only.
1568
+ Height of the timeline date strip: 16, 20, 24, 32 or 40 px from
1569
+ .Sy xs
1570
+ to
1571
+ .Sy xl ,
1572
+ with the date labels kept vertically centred.
1573
+ It sizes the top strip and the mirrored bottom strip alike.
1574
+ .Sy none
1575
+ removes every date strip, including the ones
1576
+ .Sy timeline-position
1577
+ asks for; with
1578
+ .Sy bottom
1579
+ or
1580
+ .Sy both
1581
+ that draws the warning
1582
+ .Sy NL.W0704 .
1200
1583
  .It Sy corner-radius
1201
1584
  .Sy none | xs | sm | md | lg | xl | full .
1202
1585
  .It Sy bracket
1203
- .Sy none Pq default | solid | dashed .
1204
- Parallel-only.
1586
+ .Sy none | solid | dashed .
1587
+ The header bracket over a group's or parallel's dates:
1588
+ .Sy solid
1589
+ by default on a group,
1590
+ .Sy dashed
1591
+ on a parallel;
1592
+ .Sy none
1593
+ hides it.
1594
+ Containers only.
1205
1595
  .It Sy capacity-icon
1206
1596
  Glyph used as the suffix to capacity numbers.
1207
1597
  Built-in identifiers:
@@ -1217,6 +1607,16 @@ Built-in identifiers:
1217
1607
  Custom: any
1218
1608
  .Sy symbol
1219
1609
  id; inline: a double-quoted Unicode literal.
1610
+ .It Sy header-position
1611
+ .Sy beside Pq default | above .
1612
+ Roadmap-only.
1613
+ Where the roadmap header card (title and author) sits:
1614
+ .Sy beside
1615
+ puts it in a column left of the chart, 120 to 240 px wide, with the
1616
+ title wrapping to fit;
1617
+ .Sy above
1618
+ puts it in a full-width 72 px band above the chart, which then spans
1619
+ the whole canvas width.
1220
1620
  .It Sy timeline-position
1221
1621
  .Sy top Pq default | bottom | both .
1222
1622
  Roadmap-only.
@@ -1228,6 +1628,21 @@ Roadmap-only.
1228
1628
  When
1229
1629
  .Sy true ,
1230
1630
  draws faint dotted grid lines at every tick boundary.
1631
+ .It Sy non-working
1632
+ .Sy hide Pq default | show .
1633
+ Roadmap-only; set it on
1634
+ .Sy default roadmap .
1635
+ Under a calendar that has non-working days
1636
+ .Pq Sy calendar:business ,
1637
+ .Sy hide
1638
+ collapses them to a seam and
1639
+ .Sy show
1640
+ draws each run at full width as a shaded band that bars paint across.
1641
+ The
1642
+ .Fl -non-working
1643
+ option of
1644
+ .Xr nowline 1
1645
+ and its equivalent on every other surface override it.
1231
1646
  .El
1232
1647
  .Pp
1233
1648
  Built-in icon names are rendered from a curated SVG library
@@ -1275,7 +1690,7 @@ Identifiers match
1275
1690
  letters, digits, underscores, and dashes, starting with a letter
1276
1691
  or underscore.
1277
1692
  They must be unique across the merged result (the file and all
1278
- its includes); items, parallel blocks, groups, anchors, persons,
1693
+ its includes); items, parallel blocks, groups, anchors, waves, persons,
1279
1694
  teams, milestones, footnotes share one namespace.
1280
1695
  .Pp
1281
1696
  Idiomatic Nowline uses kebab-case but
@@ -1306,7 +1721,7 @@ and
1306
1721
  .Sy before:
1307
1722
  each accept a single identifier or a bracketed list.
1308
1723
  References may target items, milestones, anchors, parallel
1309
- blocks, or groups.
1724
+ blocks, groups, or waves.
1310
1725
  .Bl -bullet -offset indent -compact
1311
1726
  .It
1312
1727
  .Sy after:id
@@ -1326,6 +1741,17 @@ referenced entities finish (i.e. after the latest of them).
1326
1741
  \(em finishes before the
1327
1742
  .Em earliest
1328
1743
  of the referenced entities starts.
1744
+ .It
1745
+ .Sy after:wave
1746
+ \(em starts no earlier than the
1747
+ .Em end
1748
+ of the wave.
1749
+ .Sy before:wave
1750
+ \(em should finish before the
1751
+ .Em start
1752
+ of the wave.
1753
+ .Sy on:wave
1754
+ \(em attaches a footnote to the wave.
1329
1755
  .El
1330
1756
  .Pp
1331
1757
  Circular dependencies across the full graph (including every
@@ -1371,7 +1797,8 @@ declaration per file (subject to
1371
1797
  mode).
1372
1798
  .It
1373
1799
  All identifiers are unique across the merged result.
1374
- Parent wins on collision, with a warning.
1800
+ Parent wins on collision, with a warning (waves excepted; see
1801
+ .Sx INCLUDES ) .
1375
1802
  .It
1376
1803
  Every entity must have at least an identifier or a title (or
1377
1804
  both).
@@ -1400,8 +1827,9 @@ line.
1400
1827
  .It
1401
1828
  .Sy label ,
1402
1829
  .Sy size ,
1830
+ .Sy status ,
1403
1831
  and
1404
- .Sy status
1832
+ .Sy wave
1405
1833
  declarations must appear in the roadmap section.
1406
1834
  Placing them before
1407
1835
  .Sy roadmap
@@ -1418,12 +1846,13 @@ and
1418
1846
  must resolve to declared identifiers within the merged scope.
1419
1847
  .It
1420
1848
  A
1421
- .Sy size:
1849
+ .Sy size: ,
1850
+ .Sy status: ,
1422
1851
  or
1423
- .Sy status:
1852
+ .Sy wave:
1424
1853
  reference must resolve to a declaration that appears
1425
1854
  .Em earlier in the file
1426
- (or in an earlier include).
1855
+ (or in an earlier include; waves are never contributed by includes).
1427
1856
  Forward references are an error.
1428
1857
  .It
1429
1858
  No circular dependencies in
@@ -1480,6 +1909,39 @@ fraction, or
1480
1909
  When both numeric thresholds are set,
1481
1910
  .Sy warn-at \(<= over-at .
1482
1911
  .It
1912
+ Style values, in a
1913
+ .Sy style
1914
+ block or on a
1915
+ .Sy default
1916
+ line:
1917
+ .Sy bg: , fg: ,
1918
+ and
1919
+ .Sy text:
1920
+ take a named color, a hex value, or
1921
+ .Sy none
1922
+ .Pq Sy NL.E0801 ;
1923
+ a key with a fixed set of values, such as
1924
+ .Sy border: , shadow: ,
1925
+ or
1926
+ .Sy font: ,
1927
+ takes one of them
1928
+ .Pq Sy NL.E0802 .
1929
+ A key in a
1930
+ .Sy style
1931
+ block that is not a style property is
1932
+ .Sy NL.E0803 .
1933
+ .It
1934
+ A raw style property
1935
+ .Pq Sy bg: , Sy icon: , Sy capacity-icon: , No ...
1936
+ on an entity in the roadmap section is
1937
+ .Sy NL.E0804 ;
1938
+ declare a named
1939
+ .Sy style
1940
+ in
1941
+ .Sy config
1942
+ and reference it with
1943
+ .Sy style:id .
1944
+ .It
1483
1945
  .Sy capacity-icon:
1484
1946
  value must be a built-in identifier
1485
1947
  .Po
@@ -1491,6 +1953,56 @@ declaration in scope, or a double-quoted Unicode literal.
1491
1953
  Same contract for
1492
1954
  .Sy icon: .
1493
1955
  .It
1956
+ .Sy non-working:
1957
+ value must be
1958
+ .Sy hide
1959
+ or
1960
+ .Sy show ,
1961
+ on
1962
+ .Sy default roadmap
1963
+ and in a
1964
+ .Sy style
1965
+ block.
1966
+ Any other value is
1967
+ .Sy NL.E0800
1968
+ (one error per value).
1969
+ .It
1970
+ The roadmap-only style keys
1971
+ .Sy header-height , header-position , timeline-position ,
1972
+ .Sy minor-grid ,
1973
+ and
1974
+ .Sy non-working
1975
+ take effect only on
1976
+ .Sy default roadmap
1977
+ (or in a
1978
+ .Sy style
1979
+ block the roadmap references).
1980
+ On any other
1981
+ .Sy default
1982
+ line they are ignored with the warning
1983
+ .Sy NL.W0703 .
1984
+ .Sy style
1985
+ blocks are not checked.
1986
+ .It
1987
+ When the roadmap's style sets
1988
+ .Sy header-height:none
1989
+ together with
1990
+ .Sy timeline-position:bottom
1991
+ or
1992
+ .Sy both ,
1993
+ no date strip is drawn at all, which draws the warning
1994
+ .Sy NL.W0704 .
1995
+ The style resolves from
1996
+ .Sy default roadmap ,
1997
+ then the style of each label on the
1998
+ .Sy roadmap
1999
+ line (the first label winning), then its own
2000
+ .Sy style: ,
2001
+ a later key winning.
2002
+ Only styles and labels declared in the same file are read; a
2003
+ .Sy style:
2004
+ or label from an include leaves the check silent.
2005
+ .It
1494
2006
  .Sy remaining:
1495
2007
  is either a percentage
1496
2008
  .Pq Sy 0% \(en Sy 100%
@@ -1519,6 +2031,60 @@ When
1519
2031
  all four
1520
2032
  .Sy days-per-*
1521
2033
  entries are required and must be positive integers.
2034
+ .It
2035
+ A
2036
+ .Sy non-working
2037
+ or
2038
+ .Sy working
2039
+ declaration is one of three shapes: a lone
2040
+ .Sy date: ;
2041
+ .Sy start:
2042
+ and
2043
+ .Sy end:
2044
+ without
2045
+ .Sy every: ;
2046
+ or
2047
+ .Sy every:
2048
+ with optional bounds
2049
+ .Pq Sy NL.E0900 .
2050
+ Its only keys are
2051
+ .Sy date: , start: , end: ,
2052
+ and
2053
+ .Sy every:
2054
+ .Pq Sy NL.E0901 ,
2055
+ and
2056
+ .Sy start:
2057
+ and
2058
+ .Sy end:
2059
+ take one date each
2060
+ .Pq Sy NL.E0902 .
2061
+ .It
2062
+ Every date on a calendar declaration is a real calendar day
2063
+ .Pq Sy NL.E0405 ,
2064
+ and
2065
+ .Sy end:
2066
+ is not before
2067
+ .Sy start:
2068
+ .Pq Sy NL.E0903 .
2069
+ .It
2070
+ .Sy every:
2071
+ values are weekday names
2072
+ .Pq Sy NL.E0904
2073
+ and each appears at most once
2074
+ .Pq Sy NL.E0905 .
2075
+ .It
2076
+ The open-ended week keeps at least one working weekday
2077
+ .Pq Sy NL.E0906 .
2078
+ .Sy days-per-week
2079
+ agrees with the weekdays it leaves working; a mismatch is the warning
2080
+ .Sy NL.W0705 .
2081
+ .It
2082
+ A declaration id is unique within its keyword in one file
2083
+ .Pq Sy NL.E0907 .
2084
+ .Sy non-working
2085
+ and
2086
+ .Sy working
2087
+ do not share a namespace.
1522
2088
  .El
1523
2089
  .Ss Roadmap start property
1524
2090
  .Bl -bullet -offset indent -compact
@@ -1612,7 +2178,112 @@ both absent or both present with identical values.
1612
2178
  A mismatch is an error reported on the parent's
1613
2179
  .Sy include
1614
2180
  line.
2181
+ .It
2182
+ For any
2183
+ .Sy include
2184
+ whose
2185
+ .Sy roadmap:
2186
+ mode is not
2187
+ .Sy ignore ,
2188
+ a participating child (one that declares a roadmap, swimlanes, or
2189
+ waves) must declare the same waves, in the same order, with the same
2190
+ resolved start floors, as the parent
2191
+ .Pq Sy NL.E0202 .
2192
+ A differing title or other presentation is the warning
2193
+ .Sy NL.W0701 .
2194
+ .It
2195
+ On
2196
+ .Sy config:merge ,
2197
+ a
2198
+ .Sy non-working
2199
+ or
2200
+ .Sy working
2201
+ declaration collides only with a parent declaration of the same keyword
2202
+ and name, and the parent wins with a warning; unnamed declarations
2203
+ never collide.
1615
2204
  .El
2205
+ .Ss Waves
2206
+ These rules apply to files that use
2207
+ .Sy wave
2208
+ or
2209
+ .Sy wave: .
2210
+ Each has a stable diagnostic code.
2211
+ .Bl -tag -width "NL.E1100" -offset indent -compact
2212
+ .It Sy NL.E1100
2213
+ A
2214
+ .Sy wave
2215
+ declaration has no identifier.
2216
+ .It Sy NL.E1101
2217
+ A
2218
+ .Sy wave:
2219
+ value is not exactly one wave declared earlier: a list of two or
2220
+ more, an undeclared id, a forward reference, or an id of another
2221
+ kind.
2222
+ .It Sy NL.E1102
2223
+ A descendant's
2224
+ .Sy wave:
2225
+ differs from its container's.
2226
+ .It Sy NL.E1103
2227
+ The wave order cannot be realized: some work would have to start at
2228
+ or after the end of its own wave, because of lane order, a
2229
+ .Sy parallel
2230
+ join, or an
2231
+ .Sy after:
2232
+ that names the item's own wave, a later wave, or work in a later wave
2233
+ (directly or through a chain of other work).
2234
+ .It Sy NL.E1104
2235
+ .Sy wave:
2236
+ on a swimlane, a milestone, or any entity other than item, group,
2237
+ or parallel.
2238
+ .It Sy NL.E1105
2239
+ A key that is not allowed on a wave
2240
+ .Po
2241
+ .Sy before: , date: , start: , length: , duration: , size: ,
2242
+ .Sy capacity: , remaining: , wave:
2243
+ .Pc .
2244
+ .It Sy NL.E1106
2245
+ A wave's
2246
+ .Sy after:
2247
+ names something other than an anchor, a dated milestone, or one ISO
2248
+ date.
2249
+ .It Sy NL.W1100
2250
+ A
2251
+ .Sy before:
2252
+ that the wave structure guarantees can never be met.
2253
+ .It Sy NL.W1101
2254
+ An
2255
+ .Sy after:
2256
+ or
2257
+ .Sy before:
2258
+ that layout ignores in a roadmap with waves: a forward reference, a
2259
+ reference to the enclosing group or parallel, or a reference to a
2260
+ floating milestone.
2261
+ .It Sy NL.W0702
2262
+ .Sy wave:
2263
+ (including on a
2264
+ .Sy default
2265
+ line) in a roadmap that declares no waves; the key is ignored.
2266
+ .El
2267
+ .Pp
2268
+ Include agreement is
2269
+ .Sy NL.E0202
2270
+ and
2271
+ .Sy NL.W0701
2272
+ (see
2273
+ .Sx INCLUDES ) .
2274
+ Layout adds four insights:
2275
+ .Sy NL.W1002
2276
+ (the barrier solver did not settle),
2277
+ .Sy NL.I1006
2278
+ (waves with no items),
2279
+ .Sy NL.I1007
2280
+ (a wave overruns a dated milestone whose
2281
+ .Sy after:
2282
+ names it), and
2283
+ .Sy NL.I1008
2284
+ (an item whose
2285
+ .Sy after:
2286
+ date falls on a non-working day starts on the next working day).
1616
2287
  .Ss Parallel and group
1617
2288
  .Bl -bullet -offset indent -compact
1618
2289
  .It
@@ -1655,22 +2326,45 @@ A
1655
2326
  that sets a banned property
1656
2327
  .Pq see Sx CONFIG SECTION
1657
2328
  is an error.
2329
+ .It
2330
+ .Sy wave
2331
+ is banned on every
2332
+ .Sy default <entity>
2333
+ line: an error when the roadmap has waves, the warning
2334
+ .Sy NL.W0702
2335
+ when it has none.
1658
2336
  .El
1659
2337
  .Ss Symbols
1660
2338
  .Bl -bullet -offset indent -compact
1661
2339
  .It
1662
2340
  Every
1663
2341
  .Sy symbol
1664
- declaration must specify a non-empty
1665
- .Sy unicode:"<string>" .
2342
+ declaration must specify
2343
+ .Sy unicode:"<string>"
2344
+ .Pq Sy NL.E0806 ,
2345
+ and it must be non-empty
2346
+ .Pq Sy NL.E0807 .
1666
2347
  .It
1667
2348
  .Sy ascii: ,
1668
2349
  if present, must be a quoted string of length \(<= 3 ASCII
1669
- characters.
2350
+ characters
2351
+ .Pq Sy NL.E0808 .
1670
2352
  .It
1671
2353
  A
1672
2354
  .Sy symbol
1673
- id must not shadow a built-in icon name.
2355
+ takes only
2356
+ .Sy unicode: , ascii: , link: ,
2357
+ and
2358
+ .Sy description: ;
2359
+ any other property is
2360
+ .Sy NL.E0809 .
2361
+ .It
2362
+ A
2363
+ .Sy symbol
2364
+ id must not shadow a built-in icon name
2365
+ .Pq Sy NL.E0805
2366
+ and must be unique in the file
2367
+ .Pq Sy NL.E0810 .
1674
2368
  .It
1675
2369
  A
1676
2370
  .Sy symbol
@@ -1678,8 +2372,10 @@ reference
1678
2372
  .Pq Sy icon:NAME or Sy capacity-icon:NAME
1679
2373
  must resolve to a built-in or an earlier
1680
2374
  .Sy symbol
1681
- declaration.
1682
- Forward references are an error.
2375
+ declaration
2376
+ .Pq Sy NL.E0811 .
2377
+ Forward references are an error
2378
+ .Pq Sy NL.E0812 .
1683
2379
  .El
1684
2380
  .Sh EXAMPLES
1685
2381
  A complete
@@ -1766,6 +2462,38 @@ footnote "Vendor dependency" on:audit-log
1766
2462
  footnote capacity-risk "Team capacity risk" on:[mobile, platform]
1767
2463
  description "Mobile team is down to 2 engineers through Q2."
1768
2464
  .Ed
2465
+ .Pp
2466
+ A compact roadmap with waves:
2467
+ .Bd -literal -offset indent
2468
+ nowline v1
2469
+
2470
+ roadmap checkout-relaunch "Checkout relaunch" \e
2471
+ start:2026-01-05 scale:1w calendar:full
2472
+
2473
+ wave foundations "Foundations"
2474
+ wave build "Build"
2475
+ wave launch "Launch"
2476
+
2477
+ swimlane platform "Platform"
2478
+ item auth "Auth service split" duration:4w wave:foundations
2479
+ item payments-api "Payments API v2" duration:8w wave:build
2480
+ item rate-limits "Rate limits" duration:2w wave:launch
2481
+
2482
+ swimlane web "Web"
2483
+ item ux-research "Checkout UX research" duration:2w \e
2484
+ wave:foundations
2485
+ group wave:build
2486
+ item checkout-v2 "Checkout v2" duration:4w
2487
+ item a11y "Accessibility pass" duration:2w
2488
+ item launch-page "Launch page" duration:2w wave:launch
2489
+
2490
+ // No wave: background work, never held by a barrier.
2491
+ swimlane ops "Ops"
2492
+ item on-call "On-call and KTLO" duration:18w
2493
+
2494
+ milestone beta "Beta" after:build
2495
+ milestone ga "GA" after:launch
2496
+ .Ed
1769
2497
  .Sh SEE ALSO
1770
2498
  .Xr nowline 1
1771
2499
  .Pq Sy man 1 nowline