@nowline/cli 0.2.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 (139) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +372 -0
  3. package/dist/cli/args.d.ts +54 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +165 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/formats.d.ts +61 -0
  8. package/dist/cli/formats.d.ts.map +1 -0
  9. package/dist/cli/formats.js +153 -0
  10. package/dist/cli/formats.js.map +1 -0
  11. package/dist/cli/help.d.ts +3 -0
  12. package/dist/cli/help.d.ts.map +1 -0
  13. package/dist/cli/help.js +90 -0
  14. package/dist/cli/help.js.map +1 -0
  15. package/dist/cli/output-path.d.ts +57 -0
  16. package/dist/cli/output-path.d.ts.map +1 -0
  17. package/dist/cli/output-path.js +70 -0
  18. package/dist/cli/output-path.js.map +1 -0
  19. package/dist/commands/init.d.ts +20 -0
  20. package/dist/commands/init.d.ts.map +1 -0
  21. package/dist/commands/init.js +80 -0
  22. package/dist/commands/init.js.map +1 -0
  23. package/dist/commands/render.d.ts +15 -0
  24. package/dist/commands/render.d.ts.map +1 -0
  25. package/dist/commands/render.js +435 -0
  26. package/dist/commands/render.js.map +1 -0
  27. package/dist/commands/serve.d.ts +16 -0
  28. package/dist/commands/serve.d.ts.map +1 -0
  29. package/dist/commands/serve.js +287 -0
  30. package/dist/commands/serve.js.map +1 -0
  31. package/dist/convert/parse-json.d.ts +7 -0
  32. package/dist/convert/parse-json.d.ts.map +1 -0
  33. package/dist/convert/parse-json.js +34 -0
  34. package/dist/convert/parse-json.js.map +1 -0
  35. package/dist/convert/printer.d.ts +6 -0
  36. package/dist/convert/printer.d.ts.map +1 -0
  37. package/dist/convert/printer.js +334 -0
  38. package/dist/convert/printer.js.map +1 -0
  39. package/dist/convert/schema.d.ts +33 -0
  40. package/dist/convert/schema.d.ts.map +1 -0
  41. package/dist/convert/schema.js +77 -0
  42. package/dist/convert/schema.js.map +1 -0
  43. package/dist/core/parse.d.ts +24 -0
  44. package/dist/core/parse.d.ts.map +1 -0
  45. package/dist/core/parse.js +58 -0
  46. package/dist/core/parse.js.map +1 -0
  47. package/dist/diagnostics/adapt.d.ts +46 -0
  48. package/dist/diagnostics/adapt.d.ts.map +1 -0
  49. package/dist/diagnostics/adapt.js +109 -0
  50. package/dist/diagnostics/adapt.js.map +1 -0
  51. package/dist/diagnostics/format.d.ts +18 -0
  52. package/dist/diagnostics/format.d.ts.map +1 -0
  53. package/dist/diagnostics/format.js +41 -0
  54. package/dist/diagnostics/format.js.map +1 -0
  55. package/dist/diagnostics/index.d.ts +5 -0
  56. package/dist/diagnostics/index.d.ts.map +1 -0
  57. package/dist/diagnostics/index.js +5 -0
  58. package/dist/diagnostics/index.js.map +1 -0
  59. package/dist/diagnostics/json.d.ts +8 -0
  60. package/dist/diagnostics/json.d.ts.map +1 -0
  61. package/dist/diagnostics/json.js +24 -0
  62. package/dist/diagnostics/json.js.map +1 -0
  63. package/dist/diagnostics/model.d.ts +44 -0
  64. package/dist/diagnostics/model.d.ts.map +1 -0
  65. package/dist/diagnostics/model.js +2 -0
  66. package/dist/diagnostics/model.js.map +1 -0
  67. package/dist/diagnostics/text.d.ts +6 -0
  68. package/dist/diagnostics/text.d.ts.map +1 -0
  69. package/dist/diagnostics/text.js +43 -0
  70. package/dist/diagnostics/text.js.map +1 -0
  71. package/dist/generated/templates.d.ts +4 -0
  72. package/dist/generated/templates.d.ts.map +1 -0
  73. package/dist/generated/templates.js +9 -0
  74. package/dist/generated/templates.js.map +1 -0
  75. package/dist/generated/version.d.ts +11 -0
  76. package/dist/generated/version.d.ts.map +1 -0
  77. package/dist/generated/version.js +8 -0
  78. package/dist/generated/version.js.map +1 -0
  79. package/dist/i18n/locale.d.ts +56 -0
  80. package/dist/i18n/locale.d.ts.map +1 -0
  81. package/dist/i18n/locale.js +107 -0
  82. package/dist/i18n/locale.js.map +1 -0
  83. package/dist/index.d.ts +3 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +60 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/io/config.d.ts +2 -0
  88. package/dist/io/config.d.ts.map +1 -0
  89. package/dist/io/config.js +5 -0
  90. package/dist/io/config.js.map +1 -0
  91. package/dist/io/exit-codes.d.ts +12 -0
  92. package/dist/io/exit-codes.d.ts.map +1 -0
  93. package/dist/io/exit-codes.js +15 -0
  94. package/dist/io/exit-codes.js.map +1 -0
  95. package/dist/io/read.d.ts +13 -0
  96. package/dist/io/read.d.ts.map +1 -0
  97. package/dist/io/read.js +53 -0
  98. package/dist/io/read.js.map +1 -0
  99. package/dist/io/write.d.ts +32 -0
  100. package/dist/io/write.d.ts.map +1 -0
  101. package/dist/io/write.js +61 -0
  102. package/dist/io/write.js.map +1 -0
  103. package/dist/version.d.ts +13 -0
  104. package/dist/version.d.ts.map +1 -0
  105. package/dist/version.js +20 -0
  106. package/dist/version.js.map +1 -0
  107. package/man/fr/nowline.1 +424 -0
  108. package/man/fr/nowline.5 +1864 -0
  109. package/man/nowline.1 +517 -0
  110. package/man/nowline.5 +1784 -0
  111. package/package.json +66 -0
  112. package/scripts/bundle-templates.mjs +105 -0
  113. package/scripts/compile.mjs +131 -0
  114. package/src/cli/args.ts +252 -0
  115. package/src/cli/formats.ts +207 -0
  116. package/src/cli/help.ts +92 -0
  117. package/src/cli/output-path.ts +98 -0
  118. package/src/commands/init.ts +99 -0
  119. package/src/commands/render.ts +566 -0
  120. package/src/commands/serve.ts +322 -0
  121. package/src/convert/parse-json.ts +57 -0
  122. package/src/convert/printer.ts +376 -0
  123. package/src/convert/schema.ts +105 -0
  124. package/src/core/parse.ts +93 -0
  125. package/src/diagnostics/adapt.ts +148 -0
  126. package/src/diagnostics/format.ts +70 -0
  127. package/src/diagnostics/index.ts +4 -0
  128. package/src/diagnostics/json.ts +30 -0
  129. package/src/diagnostics/model.ts +48 -0
  130. package/src/diagnostics/text.ts +62 -0
  131. package/src/generated/templates.ts +12 -0
  132. package/src/generated/version.ts +18 -0
  133. package/src/i18n/locale.ts +133 -0
  134. package/src/index.ts +60 -0
  135. package/src/io/config.ts +11 -0
  136. package/src/io/exit-codes.ts +18 -0
  137. package/src/io/read.ts +70 -0
  138. package/src/io/write.ts +94 -0
  139. package/src/version.ts +21 -0
package/LICENSE ADDED
@@ -0,0 +1,190 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to the Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by the Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding any notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ Copyright 2026 Lolay, Inc.
179
+
180
+ Licensed under the Apache License, Version 2.0 (the "License");
181
+ you may not use this file except in compliance with the License.
182
+ You may obtain a copy of the License at
183
+
184
+ http://www.apache.org/licenses/LICENSE-2.0
185
+
186
+ Unless required by applicable law or agreed to in writing, software
187
+ distributed under the License is distributed on an "AS IS" BASIS,
188
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
+ See the License for the specific language governing permissions and
190
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,372 @@
1
+ # @nowline/cli
2
+
3
+ The `nowline` command-line tool parses, validates, and renders `.nowline` roadmap files.
4
+
5
+ **License:** Apache 2.0
6
+ **Part of:** [`lolay/nowline`](https://github.com/lolay/nowline) monorepo
7
+
8
+ ## Install
9
+
10
+ A single `nowline` binary ships every export format (SVG, PNG, PDF, HTML,
11
+ Markdown+Mermaid, XLSX, MS Project XML) plus AST round-trip
12
+ (`json` ↔ `nowline`). Approximate size: ~70 MB (the bun runtime is
13
+ ~60 MB of that — see
14
+ [`specs/cli-distribution.md`](../../specs/cli-distribution.md) for why
15
+ we don't ship a smaller "tiny" tier).
16
+
17
+ ```bash
18
+ # macOS / Linux / WSL — Homebrew
19
+ brew install lolay/tap/nowline
20
+
21
+ # Debian / Ubuntu — download .deb from GitHub Releases
22
+ curl -L -o nowline.deb \
23
+ https://github.com/lolay/nowline/releases/latest/download/nowline_amd64.deb
24
+ sudo dpkg -i nowline.deb
25
+
26
+ # Windows — direct .exe download from GitHub Releases
27
+ # nowline-windows-x64.exe
28
+ # (unsigned; see SmartScreen walkthrough below)
29
+
30
+ # npm (any platform)
31
+ npm install -g @nowline/cli
32
+ # or one-shot: npx @nowline/cli roadmap.nowline -o -
33
+ ```
34
+
35
+ After any of the package-manager installs above, `man nowline` shows the
36
+ CLI manual (flags + a `LANGUAGE` cheatsheet) and `man 5 nowline` shows
37
+ the full `.nowline` DSL reference. The Homebrew formula's
38
+ `resource "manpage"` / `resource "manpage5"`, the `.deb`'s
39
+ `/usr/share/man/man1/nowline.1.gz` / `/usr/share/man/man5/nowline.5.gz`,
40
+ and npm's `"man"` field (which lists both files) all install the same
41
+ hand-authored mdoc sources from [`man/nowline.1`](./man/nowline.1) and
42
+ [`man/nowline.5`](./man/nowline.5). For direct binary downloads from
43
+ GitHub Releases, both man pages ship as separate `nowline.1` and
44
+ `nowline.5` assets alongside the platform binaries.
45
+
46
+ ## Usage
47
+
48
+ `nowline` is **verbless**: rendering is the default. Other modes are flags on the same command:
49
+
50
+ ```bash
51
+ nowline <input> [options] # render (default)
52
+ nowline <input> --serve [-p <port>] # live HTTP preview
53
+ nowline --init [<name>] # scaffold a starter file
54
+ nowline <input> --dry-run # validate-only (no write)
55
+ nowline --help # print help
56
+ nowline --version # print version
57
+ nowline # no args → print help
58
+ ```
59
+
60
+ ### Examples
61
+
62
+ ```bash
63
+ nowline roadmap.nowline # writes ./roadmap.svg in cwd
64
+ nowline roadmap.nowline -f png # writes ./roadmap.png
65
+ nowline roadmap.nowline -f pdf # writes ./roadmap.pdf
66
+ nowline roadmap.nowline -f html # writes ./roadmap.html
67
+ nowline roadmap.nowline -f mermaid # writes ./roadmap.md
68
+ nowline roadmap.nowline -f xlsx # writes ./roadmap.xlsx
69
+ nowline roadmap.nowline -f msproj # writes ./roadmap.xml
70
+ nowline roadmap.nowline -o roadmap.pdf # format inferred from extension
71
+ nowline roadmap.nowline -o - # SVG → stdout (Unix dash)
72
+ nowline roadmap.json -f svg # JSON-AST input
73
+ cat foo.nowline | nowline - # stdin → ./roadmap.svg
74
+ nowline roadmap.nowline -f json -o roadmap.json # convert text → JSON
75
+ nowline roadmap.nowline --dry-run # validate-only; nothing written
76
+ nowline roadmap.nowline --serve -p 8080 # live preview on :8080
77
+ nowline --init # ./roadmap.nowline
78
+ nowline --init my-project # ./my-project.nowline
79
+ nowline roadmap.nowline -f pdf -o report # auto-extension → report.pdf
80
+ nowline roadmap.nowline -f pdf --page-size a4 --orientation landscape --margin 0.5in
81
+ nowline roadmap.nowline -f png --scale 3 # 3x raster
82
+ nowline roadmap.nowline --headless # bundled DejaVu fonts (deterministic)
83
+ ```
84
+
85
+ ## Flags
86
+
87
+ ### I/O
88
+
89
+ | Flag | Default | Notes |
90
+ |----------------------------|----------------------------------------|------------------------------------------------|
91
+ | `-f, --format <fmt>` | inferred | `svg`, `png`, `pdf`, `html`, `mermaid`, `xlsx`, `msproj`, `json`, `nowline`. |
92
+ | `-o, --output <path>` | `<cwd>/<input-base>.<format>` | `-` for stdout. Existing files silently overwritten. |
93
+ | `--input-format <fmt>` | by extension; stdin → `nowline` | `nowline` or `json`. |
94
+
95
+ ### Mode flags (mutually exclusive)
96
+
97
+ | Flag | Description |
98
+ |---------------------|-------------------------------------------------------------------|
99
+ | `--serve` | Live HTTP preview. Opt-in `-o <path>` writes on each rebuild. |
100
+ | `--init [<name>]` | Scaffold a starter `.nowline` in cwd. Auto-appends `.nowline`. |
101
+ | `-n, --dry-run` | Run pipeline; skip the write. Replaces the old `validate` verb. |
102
+
103
+ ### Render options
104
+
105
+ | Flag | Default | Notes |
106
+ |-----------------------|--------------|---------------------------------------------|
107
+ | `-t, --theme <name>` | `light` | `light` \| `dark`. |
108
+ | `--now YYYY-MM-DD` | today (UTC) | Override the now-line anchor date. Use `--now -` to suppress it. |
109
+ | `--no-links` | (off) | Omit link icons from items. |
110
+ | `-s, --scale <n>` | `1` | Raster scale (PNG only). |
111
+ | `--strict` | (off) | Promote asset / sanitizer warnings to errors. |
112
+ | `-w, --width <px>` | `1280` | Canvas width. |
113
+ | `--asset-root <dir>` | input dir | Root for `logo:` / image refs. |
114
+
115
+ ### Format-specific options
116
+
117
+ | Flag | Default | Applies to | Notes |
118
+ |----------------------------|--------------|------------|-------|
119
+ | `--page-size <size>` | `letter` | pdf | Preset (`letter`, `legal`, `tabloid`, `ledger`, `a1`–`a5`, `b3`–`b5`), `content` for auto-fit, or `WxHunit` for custom (`8.5x11in`, `210x297mm`). |
120
+ | `--orientation <name>` | `auto` | pdf | `portrait` \| `landscape` \| `auto`. |
121
+ | `--margin <length>` | `36pt` | pdf | Page margin. Bare numbers are points; `0.5in`, `12mm`, `1cm` accepted. |
122
+ | `--font-sans <path\|alias>` | platform-resolved | png, pdf | TTF/OTF path, or alias `sf`, `helvetica`, `dejavu`, etc. |
123
+ | `--font-mono <path\|alias>` | platform-resolved | png, pdf | TTF/OTF path or alias for monospace. |
124
+ | `--headless` | (off) | png, pdf | Skip platform font probe; use bundled DejaVu pair. Byte-stable across machines. |
125
+ | `--start YYYY-MM-DD` | `today` | msproj | Anchor date for relative-only roadmaps. |
126
+
127
+ ### Serve options
128
+
129
+ | Flag | Default |
130
+ |----------------------|-------------|
131
+ | `-p, --port <n>` | `4318` |
132
+ | `--host <host>` | `127.0.0.1` |
133
+ | `--open` | (off) |
134
+
135
+ ### Logging (mutually exclusive)
136
+
137
+ | Flag | Description |
138
+ |------------------|--------------------------------------|
139
+ | `-v, --verbose` | Extra diagnostics on stderr. |
140
+ | `-q, --quiet` | Suppress non-error stderr. |
141
+
142
+ ### Standard
143
+
144
+ | Flag | Description |
145
+ |------------------|--------------------------------------|
146
+ | `-h, --help` | Print help, exit 0. |
147
+ | `-V, --version` | Print version, exit 0. |
148
+
149
+ ## Behavior contracts
150
+
151
+ ### Format resolution (precedence chain)
152
+
153
+ 1. **`-f / --format` flag** — explicit always wins.
154
+ 2. **`-o <path>` extension** — recognized: `.svg`, `.png`, `.pdf`, `.html`/`.htm`, `.md`/`.markdown` (mermaid), `.xlsx`, `.json`, `.nowline`. `.xml` is **ambiguous** and requires `-f msproj`.
155
+ 3. **`.nowlinerc` `defaultFormat`** — project default.
156
+ 4. **`svg`** — built-in fallback.
157
+
158
+ If `-f` and `-o` extension disagree, `-f` wins and the output filename is preserved as written (no auto-rename).
159
+
160
+ ### Output extension auto-add
161
+
162
+ - `-o report -f pdf` → `report.pdf` (no extension → append canonical).
163
+ - `-o report.pdf -f pdf` → `report.pdf` (matching → leave alone).
164
+ - `-o foo.txt -f pdf` → `foo.txt` (mismatched → leave alone, write PDF bytes there).
165
+ - `-o -` (stdout) is never rewritten.
166
+
167
+ ### Default output paths
168
+
169
+ All default-named outputs land in **cwd**:
170
+
171
+ - File input: `<cwd>/<input-base>.<format>`.
172
+ - Stdin input: `<cwd>/roadmap.<format>`.
173
+ - `--init` (no `-o`): `<cwd>/<name>.nowline` (default name `roadmap`).
174
+
175
+ Existing files are silently overwritten — no `--force` flag, matching POSIX redirection and peer tools (mmdc, d2, prettier, tsc).
176
+
177
+ ### Stdout
178
+
179
+ - `-o -` is the only way to write to stdout (Unix dash convention).
180
+ - Binary formats (png, pdf, xlsx) on a TTY are refused with exit 2 (`nowline: binary output (png) to terminal refused; use -o or pipe to a file`). Pipes / redirects are fine.
181
+
182
+ ### Mode dispatch
183
+
184
+ Mutual exclusivity rules (all exit 2 with a message):
185
+
186
+ - `--serve` + `--init`.
187
+ - `--dry-run` + `--serve` (serve doesn't write by default).
188
+ - `--dry-run` + `--init` (init *is* the write).
189
+ - `-v / --verbose` + `-q / --quiet`.
190
+
191
+ `nowline` (no args) prints help and exits 0 (matches git, kubectl, gh, cargo, docker).
192
+
193
+ ### Exit codes
194
+
195
+ | Code | Meaning |
196
+ |------|---------|
197
+ | 0 | Success |
198
+ | 1 | Validation error |
199
+ | 2 | Usage error (missing input, bad flags, unsupported format, file not found, binary→TTY refusal) |
200
+ | 3 | Output error (cannot write to destination, exporter failure, page too small for margin) |
201
+
202
+ ## Configuration: `.nowlinerc`
203
+
204
+ On any operation that takes an `<input>` file, `nowline` walks up from the input file's directory looking for a `.nowlinerc` (JSON or YAML). The nearest one wins. CLI flags override config values. Environment variables are not consulted.
205
+
206
+ ```yaml
207
+ # .nowlinerc (YAML)
208
+ theme: dark
209
+ defaultFormat: svg
210
+ width: 1200
211
+
212
+ # m2c format defaults — override with CLI flags at any time
213
+ pdfPageSize: a4 # --page-size
214
+ pdfOrientation: landscape # --orientation
215
+ pdfMargin: 0.5in # --margin
216
+ fontSans: sf # --font-sans (alias or path)
217
+ fontMono: sf-mono # --font-mono
218
+ headlessFonts: false # --headless
219
+ ```
220
+
221
+ ```json
222
+ {
223
+ "theme": "dark",
224
+ "defaultFormat": "svg",
225
+ "width": 1200,
226
+ "pdfPageSize": "a4",
227
+ "pdfOrientation": "landscape",
228
+ "pdfMargin": "0.5in",
229
+ "fontSans": "sf",
230
+ "fontMono": "sf-mono",
231
+ "headlessFonts": false
232
+ }
233
+ ```
234
+
235
+ Unknown keys are ignored.
236
+
237
+ ## Validation (`--dry-run`)
238
+
239
+ ```bash
240
+ nowline roadmap.nowline --dry-run
241
+ nowline roadmap.nowline -n # short alias
242
+ nowline roadmap.nowline -n --diagnostic-format json
243
+ ```
244
+
245
+ Each diagnostic is rendered in a biome/oxc-style frame via `@babel/code-frame`:
246
+
247
+ ```
248
+ roadmap.nowline:7:34 error: Unknown reference 'auth-refactro' in after — did you mean 'auth-refactor'?
249
+ 5 | item auth-refactor "Auth refactor" size:l
250
+ 6 | parallel after:auth-refactor
251
+ > 7 | group audit-track "Audit Track" labels:security
252
+ | ^^^^^^^^^^^^^^^
253
+ 8 | item audit-log "Audit log v2" size:xl before:code-freeze
254
+ ```
255
+
256
+ `--diagnostic-format json` emits the stable diagnostic schema:
257
+
258
+ ```ts
259
+ type Diagnostic = {
260
+ file: string;
261
+ line: number; // 1-based
262
+ column: number; // 1-based
263
+ severity: 'error' | 'warning';
264
+ code: string;
265
+ message: string;
266
+ suggestion?: string;
267
+ };
268
+ ```
269
+
270
+ Exit 0 if no errors; exit 1 if any errors. Warnings never change the exit code.
271
+
272
+ ## JSON AST round-trip
273
+
274
+ `-f json` emits the JSON AST; `-f nowline` re-prints canonical `.nowline`:
275
+
276
+ ```bash
277
+ nowline roadmap.nowline -f json -o roadmap.json # text → JSON
278
+ nowline roadmap.json -f nowline -o roadmap.nowline # JSON → text (canonical)
279
+ ```
280
+
281
+ The JSON form is a **versioned, published contract** (`$nowlineSchema: "1"`) intended for MCP (m7) and editor (m5) round-trips:
282
+
283
+ ```ts
284
+ type NowlineDocument = {
285
+ $nowlineSchema: "1";
286
+ file: { uri: string; source: string };
287
+ ast: NowlineFileNode;
288
+ };
289
+ ```
290
+
291
+ Every node carries `$type`, `$position`, and the properties defined by the corresponding `@nowline/core` AST interface. Container back-references (`$container`, `$containerProperty`, `$containerIndex`) are omitted — parent-child relationship is captured by document structure.
292
+
293
+ ### Canonical `.nowline` printer rules
294
+
295
+ - **Indent:** 2 spaces.
296
+ - **Positional order on declaration lines:** `id` → `title` → keyed properties.
297
+ - **Keyed-property order:** `date, length, on, duration, status, owner, after, before, remaining, labels, style, link, (any remaining keys, alphabetical)`.
298
+ - **List shape:** single-element lists render as bare (`labels:enterprise`); multi-element lists use bracket form (`labels:[enterprise, security]`).
299
+ - **`description` sub-directive:** rendered on its own line indented one level under its host.
300
+ - **Comments:** not preserved across round-trips. Documented limitation; a follow-up grammar ticket will add trivia support.
301
+
302
+ Round-trip property: for every file in `examples/`, `text → json → text` and `json → text → json` are idempotent modulo comment loss. Enforced by the test suite.
303
+
304
+ ## `--serve`
305
+
306
+ Live-reload preview. Opens a minimal HTML shell at `http://<host>:<port>/` that fetches `/svg` and subscribes to `/events` (SSE). On file changes, the server re-parses, re-validates, re-lays-out, and re-renders; clients refresh automatically. Validation errors appear as an overlay on top of the most recent successful render.
307
+
308
+ ```bash
309
+ nowline roadmap.nowline --serve
310
+ nowline roadmap.nowline --serve -p 4400 -t dark --open
311
+ nowline roadmap.nowline --serve -o latest.svg # rewrites latest.svg on each rebuild
312
+ ```
313
+
314
+ `--serve` is intended for local authoring only. It is not a production preview service. `-o -` (stdout) is rejected.
315
+
316
+ ## `--init`
317
+
318
+ Create a starter `.nowline` file in the current directory. Three templates (`minimal`, `teams`, `product`) correspond to the three files in `examples/` and are embedded into the CLI at build time — binaries are self-contained.
319
+
320
+ - Positional argument is the **project name**, not a file path.
321
+ - `.nowline` is auto-appended if missing.
322
+ - Other extensions (`.txt`, `.json`) are rejected with exit 2.
323
+ - Existing files are silently overwritten.
324
+
325
+ ```bash
326
+ nowline --init # ./roadmap.nowline (default name)
327
+ nowline --init my-project # ./my-project.nowline (auto-append)
328
+ nowline --init my-plan.nowline # ./my-plan.nowline (literal)
329
+ nowline --init --template product # use the product template
330
+ ```
331
+
332
+ ## Arg parser choice
333
+
334
+ `@nowline/cli` parses arguments with Node's native [`util.parseArgs`](https://nodejs.org/api/util.html#utilparseargsconfig). Reasons:
335
+
336
+ - Zero runtime dependency.
337
+ - Native short/long flag support, kebab-case option names, mixed-position positionals, and the `--` end-of-options sentinel.
338
+ - Verbless dispatch is straightforward — modes are just boolean flags resolved after parsing.
339
+
340
+ Supporting libraries:
341
+
342
+ - [`@babel/code-frame`](https://babeljs.io/docs/babel-code-frame) — biome/oxc-style source excerpts with caret/tilde underlines for `--dry-run` text output.
343
+ - [`js-yaml`](https://github.com/nodeca/js-yaml) — `.nowlinerc` YAML parsing (JSON also supported).
344
+
345
+ ## Distribution
346
+
347
+ A single `nowline` binary ships per platform, bundling every
348
+ `@nowline/export-*` package. Compiled with `bun build --compile`; the
349
+ CLI's format dispatch uses dynamic `import()` of each per-format package
350
+ so the heavy exporter deps stay off cold paths and the binary stays
351
+ straightforward to slim down later if a profile change ever justifies
352
+ re-introducing a tier (see
353
+ [`specs/cli-distribution.md`](../../specs/cli-distribution.md)).
354
+
355
+ Six platform binaries ship per release (macOS arm64/x64, Linux
356
+ x64/arm64, Windows x64/arm64), attached to every GitHub Release. Size
357
+ budgets are per target (Bun's standalone runtime varies by ~50 MB across
358
+ platforms): macOS-arm64 ~70 MB, macOS-x64 ~75 MB, Linux ~107 MB, Windows
359
+ ~119–122 MB. CI asserts on disk for every target via
360
+ [`packages/cli/scripts/compile.mjs`](./scripts/compile.mjs). See
361
+ [`specs/cli-distribution.md`](../../specs/cli-distribution.md#size-budget)
362
+ for the full ceiling table.
363
+
364
+ ### Windows SmartScreen walkthrough
365
+
366
+ The shipped `.exe` binaries are **unsigned**. Windows may show a SmartScreen warning ("Windows protected your PC"). To run the downloaded binary:
367
+
368
+ 1. Right-click the `.exe` → **Properties**.
369
+ 2. Check **Unblock** at the bottom of the **General** tab → **OK**.
370
+ 3. Run the binary from a terminal (`cmd` or PowerShell).
371
+
372
+ Corporate endpoints may block unsigned binaries entirely. In that case, `npm install -g @nowline/cli` (which runs on Node/Bun) is an alternative.
@@ -0,0 +1,54 @@
1
+ export type ModeKind = 'render' | 'serve' | 'init' | 'help' | 'version';
2
+ export interface ParsedArgs {
3
+ /** Resolved mode after dispatch (mutual-exclusivity already checked). */
4
+ mode: ModeKind;
5
+ /** Positional argument, or undefined. Render = input path. Init = project name. Serve = input path. */
6
+ positional?: string;
7
+ /** True if `--dry-run` / `-n` was passed (only valid for render mode). */
8
+ dryRun: boolean;
9
+ /** Logging level. Verbose and quiet are mutually exclusive. */
10
+ logLevel: 'verbose' | 'quiet' | 'normal';
11
+ output?: string;
12
+ format?: string;
13
+ inputFormat?: string;
14
+ theme?: string;
15
+ /** Now-line date string from `--now`. Undefined means "use the actual
16
+ * current date" (the default). The literal value `"-"` means
17
+ * "suppress the now-line entirely" (mirrors the Unix-`-` convention
18
+ * used elsewhere in the CLI). Otherwise expected as YYYY-MM-DD;
19
+ * parsed downstream by resolveNowArg. */
20
+ now?: string;
21
+ noLinks: boolean;
22
+ scale?: string;
23
+ strict: boolean;
24
+ width?: string;
25
+ assetRoot?: string;
26
+ pageSize?: string;
27
+ orientation?: string;
28
+ margin?: string;
29
+ fontSans?: string;
30
+ fontMono?: string;
31
+ headless: boolean;
32
+ start?: string;
33
+ /**
34
+ * BCP-47 locale override (`fr-CA`, `fr`, …). When omitted the CLI
35
+ * falls back to `LC_ALL` / `LC_MESSAGES` / `LANG`, then to the
36
+ * file's `nowline v1 locale:` directive, then to `en-US`. See
37
+ * `specs/localization.md`.
38
+ */
39
+ locale?: string;
40
+ port?: string;
41
+ host?: string;
42
+ open: boolean;
43
+ diagnosticFormat?: string;
44
+ template?: string;
45
+ }
46
+ /**
47
+ * Pure argument parser. Walks `argv` once, identifies mode flags, applies
48
+ * mutual-exclusivity rules, and returns a fully-resolved `ParsedArgs`. Throws
49
+ * `CliError(ExitCode.InputError)` for usage errors.
50
+ *
51
+ * Help / version short-circuit any other flag combinations.
52
+ */
53
+ export declare function parseArgv(argv: readonly string[]): ParsedArgs;
54
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAExE,MAAM,WAAW,UAAU;IACvB,yEAAyE;IACzE,IAAI,EAAE,QAAQ,CAAC;IACf,uGAAuG;IACvG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IAGzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;8CAI0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IAGd,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAsK7D"}