@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
@@ -0,0 +1,165 @@
1
+ import { parseArgs } from 'node:util';
2
+ import { CliError, ExitCode } from '../io/exit-codes.js';
3
+ /**
4
+ * Pure argument parser. Walks `argv` once, identifies mode flags, applies
5
+ * mutual-exclusivity rules, and returns a fully-resolved `ParsedArgs`. Throws
6
+ * `CliError(ExitCode.InputError)` for usage errors.
7
+ *
8
+ * Help / version short-circuit any other flag combinations.
9
+ */
10
+ export function parseArgv(argv) {
11
+ if (argv.length === 0) {
12
+ return {
13
+ mode: 'help',
14
+ dryRun: false,
15
+ logLevel: 'normal',
16
+ noLinks: false,
17
+ strict: false,
18
+ open: false,
19
+ headless: false,
20
+ };
21
+ }
22
+ const config = {
23
+ args: argv,
24
+ allowPositionals: true,
25
+ strict: true,
26
+ options: {
27
+ help: { type: 'boolean', short: 'h' },
28
+ version: { type: 'boolean', short: 'V' },
29
+ verbose: { type: 'boolean', short: 'v' },
30
+ quiet: { type: 'boolean', short: 'q' },
31
+ output: { type: 'string', short: 'o' },
32
+ format: { type: 'string', short: 'f' },
33
+ 'input-format': { type: 'string' },
34
+ serve: { type: 'boolean' },
35
+ init: { type: 'boolean' },
36
+ 'dry-run': { type: 'boolean', short: 'n' },
37
+ theme: { type: 'string', short: 't' },
38
+ // `--now <date>` overrides the now-line position; without it, the
39
+ // CLI defaults to today's calendar date. Use `--now -` to
40
+ // suppress the now-line entirely (Unix-`-` sentinel; same idea
41
+ // as `-o -` for stdout).
42
+ now: { type: 'string' },
43
+ 'no-links': { type: 'boolean' },
44
+ scale: { type: 'string', short: 's' },
45
+ strict: { type: 'boolean' },
46
+ width: { type: 'string', short: 'w' },
47
+ 'asset-root': { type: 'string' },
48
+ port: { type: 'string', short: 'p' },
49
+ host: { type: 'string' },
50
+ open: { type: 'boolean' },
51
+ 'diagnostic-format': { type: 'string' },
52
+ template: { type: 'string' },
53
+ // Format-specific (m2c)
54
+ 'page-size': { type: 'string' },
55
+ orientation: { type: 'string' },
56
+ margin: { type: 'string' },
57
+ 'font-sans': { type: 'string' },
58
+ 'font-mono': { type: 'string' },
59
+ headless: { type: 'boolean' },
60
+ start: { type: 'string' },
61
+ // Localization (m-loc-b)
62
+ locale: { type: 'string' },
63
+ },
64
+ };
65
+ let parsed;
66
+ try {
67
+ parsed = parseArgs(config);
68
+ }
69
+ catch (err) {
70
+ const message = err instanceof Error ? err.message : String(err);
71
+ throw new CliError(ExitCode.InputError, formatUsageError(message));
72
+ }
73
+ const values = parsed.values;
74
+ const positionals = parsed.positionals;
75
+ if (values.help === true) {
76
+ return {
77
+ mode: 'help',
78
+ dryRun: false,
79
+ logLevel: 'normal',
80
+ noLinks: false,
81
+ strict: false,
82
+ open: false,
83
+ headless: false,
84
+ };
85
+ }
86
+ if (values.version === true) {
87
+ return {
88
+ mode: 'version',
89
+ dryRun: false,
90
+ logLevel: 'normal',
91
+ noLinks: false,
92
+ strict: false,
93
+ open: false,
94
+ headless: false,
95
+ };
96
+ }
97
+ if (values.verbose === true && values.quiet === true) {
98
+ throw new CliError(ExitCode.InputError, 'nowline: --verbose and --quiet are mutually exclusive.');
99
+ }
100
+ const modes = [];
101
+ if (values.serve === true)
102
+ modes.push('serve');
103
+ if (values.init === true)
104
+ modes.push('init');
105
+ if (modes.length > 1) {
106
+ throw new CliError(ExitCode.InputError, `nowline: --${modes[0]} and --${modes[1]} are mutually exclusive.`);
107
+ }
108
+ const dryRun = values['dry-run'] === true;
109
+ const mode = modes[0] ?? 'render';
110
+ if (dryRun && (mode === 'serve' || mode === 'init')) {
111
+ throw new CliError(ExitCode.InputError, `nowline: --dry-run cannot be combined with --${mode}.`);
112
+ }
113
+ if (positionals.length > 1) {
114
+ const extras = positionals
115
+ .slice(1)
116
+ .map((p) => JSON.stringify(p))
117
+ .join(' ');
118
+ throw new CliError(ExitCode.InputError, `nowline: unexpected extra arguments: ${extras}.`);
119
+ }
120
+ const logLevel = values.verbose === true ? 'verbose' : values.quiet === true ? 'quiet' : 'normal';
121
+ return {
122
+ mode,
123
+ positional: positionals[0],
124
+ dryRun,
125
+ logLevel,
126
+ output: stringOrUndefined(values.output),
127
+ format: stringOrUndefined(values.format),
128
+ inputFormat: stringOrUndefined(values['input-format']),
129
+ theme: stringOrUndefined(values.theme),
130
+ now: stringOrUndefined(values.now),
131
+ noLinks: values['no-links'] === true,
132
+ scale: stringOrUndefined(values.scale),
133
+ strict: values.strict === true,
134
+ width: stringOrUndefined(values.width),
135
+ assetRoot: stringOrUndefined(values['asset-root']),
136
+ port: stringOrUndefined(values.port),
137
+ host: stringOrUndefined(values.host),
138
+ open: values.open === true,
139
+ diagnosticFormat: stringOrUndefined(values['diagnostic-format']),
140
+ template: stringOrUndefined(values.template),
141
+ pageSize: stringOrUndefined(values['page-size']),
142
+ orientation: stringOrUndefined(values.orientation),
143
+ margin: stringOrUndefined(values.margin),
144
+ fontSans: stringOrUndefined(values['font-sans']),
145
+ fontMono: stringOrUndefined(values['font-mono']),
146
+ headless: values.headless === true,
147
+ start: stringOrUndefined(values.start),
148
+ locale: stringOrUndefined(values.locale),
149
+ };
150
+ }
151
+ function stringOrUndefined(value) {
152
+ if (typeof value === 'string')
153
+ return value;
154
+ return undefined;
155
+ }
156
+ function formatUsageError(message) {
157
+ if (message.startsWith('Unknown option')) {
158
+ return `nowline: ${message}. Try --help for usage.`;
159
+ }
160
+ if (message.includes('expected')) {
161
+ return `nowline: ${message}. Try --help for usage.`;
162
+ }
163
+ return `nowline: ${message}`;
164
+ }
165
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ export type OutputFormat = 'svg' | 'png' | 'pdf' | 'html' | 'mermaid' | 'xlsx' | 'msproj' | 'json' | 'nowline';
2
+ export type InputFormat = 'nowline' | 'json';
3
+ export declare const ALL_OUTPUT_FORMATS: readonly OutputFormat[];
4
+ export declare function isOutputFormat(value: string): value is OutputFormat;
5
+ export declare function normalizeFormatAlias(raw: string): string;
6
+ export declare function isInputFormat(value: string): value is InputFormat;
7
+ export declare function isBinaryFormat(format: OutputFormat): boolean;
8
+ export declare function isTextFormat(format: OutputFormat): boolean;
9
+ /**
10
+ * Maps a recognized output extension to its canonical format.
11
+ *
12
+ * `.xml` is intentionally absent — it is ambiguous (MS Project XML vs generic
13
+ * XML) and requires `-f msproj` to disambiguate.
14
+ */
15
+ export declare function formatFromExtension(extension: string): OutputFormat | undefined;
16
+ export declare function canonicalExtension(format: OutputFormat): string;
17
+ export interface FormatResolutionInputs {
18
+ /** `-f / --format` flag value (already lower-cased). */
19
+ flagFormat?: string;
20
+ /** `-o / --output` path; the literal string the user wrote. */
21
+ outputPath?: string;
22
+ /** `defaultFormat` from `.nowlinerc`. */
23
+ configFormat?: string;
24
+ /** True when output is `-` (stdout); skips extension inference. */
25
+ isStdout?: boolean;
26
+ }
27
+ export interface FormatResolution {
28
+ format: OutputFormat;
29
+ /** Where the format came from. Useful for `-v` diagnostics. */
30
+ source: 'flag' | 'output-extension' | 'config' | 'fallback';
31
+ }
32
+ /**
33
+ * Resolves the output format using the documented precedence chain:
34
+ *
35
+ * 1. `-f / --format` flag
36
+ * 2. `-o <path>` recognized extension (skipped for `-` / stdout)
37
+ * 3. `.nowlinerc` `defaultFormat`
38
+ * 4. Built-in fallback `svg`
39
+ *
40
+ * Returns the resolved format and the precedence step that produced it. May
41
+ * throw a `FormatResolutionError` for unsupported / ambiguous inputs (caller
42
+ * is expected to surface this as an exit-2 usage error).
43
+ */
44
+ export declare function resolveFormat(inputs: FormatResolutionInputs): FormatResolution;
45
+ /**
46
+ * Applies the documented output-extension auto-add rule:
47
+ *
48
+ * - If `<path>` ends in no extension, append the canonical extension for the
49
+ * resolved format (`-o report -f pdf` → `report.pdf`).
50
+ * - If `<path>` ends in the canonical extension for the resolved format, leave
51
+ * it alone.
52
+ * - If `<path>` ends in any *other* extension, leave it alone (no auto-rename).
53
+ * The user wrote literal bytes; we trust them.
54
+ *
55
+ * Stdout (`-`) is never rewritten; callers should bypass this helper for stdout.
56
+ */
57
+ export declare function autoAddExtension(outputPath: string, format: OutputFormat): string;
58
+ export declare class FormatResolutionError extends Error {
59
+ constructor(message: string);
60
+ }
61
+ //# sourceMappingURL=formats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/cli/formats.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAClB,KAAK,GACL,KAAK,GACL,KAAK,GACL,MAAM,GACN,SAAS,GACT,MAAM,GACN,QAAQ,GACR,MAAM,GACN,SAAS,CAAC;AAEhB,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;AAa7C,eAAO,MAAM,kBAAkB,EAAE,SAAS,YAAY,EAUrD,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,YAAY,CAEnE;AAiBD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAEjE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAE5D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAE1D;AA2BD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE/E;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAE/D;AAED,MAAM,WAAW,sBAAsB;IACnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAqC9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAMjF;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI9B"}
@@ -0,0 +1,153 @@
1
+ import * as path from 'node:path';
2
+ const TEXT_FORMATS = new Set([
3
+ 'svg',
4
+ 'html',
5
+ 'mermaid',
6
+ 'msproj',
7
+ 'json',
8
+ 'nowline',
9
+ ]);
10
+ const BINARY_FORMATS = new Set(['png', 'pdf', 'xlsx']);
11
+ export const ALL_OUTPUT_FORMATS = [
12
+ 'svg',
13
+ 'png',
14
+ 'pdf',
15
+ 'html',
16
+ 'mermaid',
17
+ 'xlsx',
18
+ 'msproj',
19
+ 'json',
20
+ 'nowline',
21
+ ];
22
+ export function isOutputFormat(value) {
23
+ return ALL_OUTPUT_FORMATS.includes(value);
24
+ }
25
+ /**
26
+ * User-facing format aliases. The canonical token is `msproj` (matches the
27
+ * package name `@nowline/export-msproj`); `ms-project` and `mspx` are
28
+ * accepted shorthands documented in `specs/handoffs/m2c.md` § 8.
29
+ */
30
+ const FORMAT_ALIASES = {
31
+ 'ms-project': 'msproj',
32
+ msproject: 'msproj',
33
+ mspx: 'msproj',
34
+ md: 'mermaid',
35
+ markdown: 'mermaid',
36
+ excel: 'xlsx',
37
+ 'ms-excel': 'xlsx',
38
+ };
39
+ export function normalizeFormatAlias(raw) {
40
+ const lower = raw.toLowerCase();
41
+ return FORMAT_ALIASES[lower] ?? lower;
42
+ }
43
+ export function isInputFormat(value) {
44
+ return value === 'nowline' || value === 'json';
45
+ }
46
+ export function isBinaryFormat(format) {
47
+ return BINARY_FORMATS.has(format);
48
+ }
49
+ export function isTextFormat(format) {
50
+ return TEXT_FORMATS.has(format);
51
+ }
52
+ const EXTENSION_MAP = new Map([
53
+ ['.svg', 'svg'],
54
+ ['.png', 'png'],
55
+ ['.pdf', 'pdf'],
56
+ ['.html', 'html'],
57
+ ['.htm', 'html'],
58
+ ['.md', 'mermaid'],
59
+ ['.markdown', 'mermaid'],
60
+ ['.xlsx', 'xlsx'],
61
+ ['.json', 'json'],
62
+ ['.nowline', 'nowline'],
63
+ ]);
64
+ const CANONICAL_EXTENSION = {
65
+ svg: '.svg',
66
+ png: '.png',
67
+ pdf: '.pdf',
68
+ html: '.html',
69
+ mermaid: '.md',
70
+ xlsx: '.xlsx',
71
+ msproj: '.xml',
72
+ json: '.json',
73
+ nowline: '.nowline',
74
+ };
75
+ /**
76
+ * Maps a recognized output extension to its canonical format.
77
+ *
78
+ * `.xml` is intentionally absent — it is ambiguous (MS Project XML vs generic
79
+ * XML) and requires `-f msproj` to disambiguate.
80
+ */
81
+ export function formatFromExtension(extension) {
82
+ return EXTENSION_MAP.get(extension.toLowerCase());
83
+ }
84
+ export function canonicalExtension(format) {
85
+ return CANONICAL_EXTENSION[format];
86
+ }
87
+ /**
88
+ * Resolves the output format using the documented precedence chain:
89
+ *
90
+ * 1. `-f / --format` flag
91
+ * 2. `-o <path>` recognized extension (skipped for `-` / stdout)
92
+ * 3. `.nowlinerc` `defaultFormat`
93
+ * 4. Built-in fallback `svg`
94
+ *
95
+ * Returns the resolved format and the precedence step that produced it. May
96
+ * throw a `FormatResolutionError` for unsupported / ambiguous inputs (caller
97
+ * is expected to surface this as an exit-2 usage error).
98
+ */
99
+ export function resolveFormat(inputs) {
100
+ if (inputs.flagFormat) {
101
+ const flag = normalizeFormatAlias(inputs.flagFormat);
102
+ if (!isOutputFormat(flag)) {
103
+ throw new FormatResolutionError(`Unknown --format "${inputs.flagFormat}". Expected one of: ${ALL_OUTPUT_FORMATS.join(', ')}.`);
104
+ }
105
+ return { format: flag, source: 'flag' };
106
+ }
107
+ if (!inputs.isStdout && inputs.outputPath) {
108
+ const ext = path.extname(inputs.outputPath);
109
+ if (ext) {
110
+ if (ext.toLowerCase() === '.xml') {
111
+ throw new FormatResolutionError('Cannot infer format from .xml extension; use -f msproj for MS Project XML output.');
112
+ }
113
+ const inferred = formatFromExtension(ext);
114
+ if (inferred) {
115
+ return { format: inferred, source: 'output-extension' };
116
+ }
117
+ }
118
+ }
119
+ if (inputs.configFormat) {
120
+ const cfg = normalizeFormatAlias(inputs.configFormat);
121
+ if (!isOutputFormat(cfg)) {
122
+ throw new FormatResolutionError(`Invalid .nowlinerc defaultFormat "${inputs.configFormat}". Expected one of: ${ALL_OUTPUT_FORMATS.join(', ')}.`);
123
+ }
124
+ return { format: cfg, source: 'config' };
125
+ }
126
+ return { format: 'svg', source: 'fallback' };
127
+ }
128
+ /**
129
+ * Applies the documented output-extension auto-add rule:
130
+ *
131
+ * - If `<path>` ends in no extension, append the canonical extension for the
132
+ * resolved format (`-o report -f pdf` → `report.pdf`).
133
+ * - If `<path>` ends in the canonical extension for the resolved format, leave
134
+ * it alone.
135
+ * - If `<path>` ends in any *other* extension, leave it alone (no auto-rename).
136
+ * The user wrote literal bytes; we trust them.
137
+ *
138
+ * Stdout (`-`) is never rewritten; callers should bypass this helper for stdout.
139
+ */
140
+ export function autoAddExtension(outputPath, format) {
141
+ const ext = path.extname(outputPath);
142
+ if (!ext) {
143
+ return outputPath + canonicalExtension(format);
144
+ }
145
+ return outputPath;
146
+ }
147
+ export class FormatResolutionError extends Error {
148
+ constructor(message) {
149
+ super(message);
150
+ this.name = 'FormatResolutionError';
151
+ }
152
+ }
153
+ //# sourceMappingURL=formats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/cli/formats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function renderHelp(): string;
2
+ export declare function renderVersion(): string;
3
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAqFA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -0,0 +1,90 @@
1
+ import { fullVersionString } from '../version.js';
2
+ // Use the dev-aware string here too: a contributor running `pnpm dev`
3
+ // against a feature branch should see e.g. `0.1.0+abc1234.dirty` in
4
+ // `--help` so it's obvious which build they're looking at.
5
+ const HELP_TEXT = `nowline ${fullVersionString()} — render, validate, and serve .nowline roadmaps.
6
+
7
+ USAGE
8
+ nowline <input> [options]
9
+ nowline --serve <input> [options]
10
+ nowline --init [<name>]
11
+ nowline --version
12
+ nowline --help
13
+
14
+ INPUT
15
+ <input> Path to .nowline or .json, or '-' for stdin.
16
+ Required for render, --serve, and --dry-run.
17
+
18
+ I/O OPTIONS
19
+ -f, --format <fmt> Output format: svg, png, pdf, html, mermaid, xlsx,
20
+ msproj, json, nowline. Default: inferred from -o
21
+ extension, else .nowlinerc 'defaultFormat', else svg.
22
+ -o, --output <path> Output file path. Use '-' for stdout (Unix dash).
23
+ Default: <cwd>/<input-base>.<format>.
24
+ Existing files are silently overwritten.
25
+ --input-format <f> Force input format: nowline | json. Default: by
26
+ extension; stdin defaults to nowline.
27
+
28
+ MODE FLAGS (mutually exclusive)
29
+ --serve Live HTTP preview server. -o opt-in writes the
30
+ rendered output to disk on each rebuild.
31
+ --init [<name>] Scaffold a starter .nowline file in cwd. Positional
32
+ becomes project name; .nowline appended if missing.
33
+ -n, --dry-run Run the full pipeline (parse + validate + layout +
34
+ format) but skip the write step. Subsumes the old
35
+ 'validate' verb. Exit 0 on success, 1 on errors.
36
+
37
+ RENDER OPTIONS
38
+ -t, --theme <name> light | dark
39
+ --now <YYYY-MM-DD> Date for the now-line. Default: today.
40
+ Use --now - to suppress the now-line.
41
+ --no-links Omit link icons from rendered items.
42
+ -s, --scale <n> Raster scale factor (PNG only; default 1).
43
+ --strict Promote asset / sanitizer warnings to errors.
44
+ -w, --width <px> Canvas width in pixels (default: 1280).
45
+ --asset-root <dir> Root for logo / image assets (default: input dir).
46
+ --locale <bcp47> BCP-47 locale (e.g. fr, fr-CA) for CLI message
47
+ output (validator diagnostics, --help, errors).
48
+ Used as a fallback for the rendered drawing only
49
+ when the file does not declare its own
50
+ 'nowline v1 locale:' directive — the file always
51
+ wins for content. Falls back to LC_ALL /
52
+ LC_MESSAGES / LANG, then en-US.
53
+
54
+ SERVE OPTIONS
55
+ -p, --port <n> Port (default: 4318).
56
+ --host <host> Bind address (default: 127.0.0.1).
57
+ --open Open the browser on start.
58
+
59
+ LOGGING (mutually exclusive)
60
+ -v, --verbose Print extra diagnostics to stderr.
61
+ -q, --quiet Suppress non-error stderr.
62
+
63
+ STANDARD
64
+ -h, --help Print this help and exit 0.
65
+ -V, --version Print version and exit 0.
66
+
67
+ EXAMPLES
68
+ nowline roadmap.nowline # writes ./roadmap.svg
69
+ nowline roadmap.nowline -f pdf # writes ./roadmap.pdf
70
+ nowline roadmap.nowline -o roadmap.pdf # format inferred from extension
71
+ nowline roadmap.nowline -o - # SVG to stdout
72
+ cat foo.nowline | nowline - # stdin → ./roadmap.svg
73
+ nowline roadmap.nowline -f json -o - # JSON AST to stdout
74
+ nowline roadmap.nowline --dry-run # validate-only
75
+ nowline roadmap.nowline --serve -p 8080 # live preview
76
+ nowline --init my-project # scaffold ./my-project.nowline
77
+
78
+ EXIT CODES
79
+ 0 Success
80
+ 1 Validation error
81
+ 2 Usage error (missing input, bad flags, format unavailable)
82
+ 3 Output error (cannot write to destination)
83
+ `;
84
+ export function renderHelp() {
85
+ return HELP_TEXT;
86
+ }
87
+ export function renderVersion() {
88
+ return `${fullVersionString()}\n`;
89
+ }
90
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,sEAAsE;AACtE,oEAAoE;AACpE,2DAA2D;AAC3D,MAAM,SAAS,GAAG,WAAW,iBAAiB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8E/C,CAAC;AAEF,MAAM,UAAU,UAAU;IACtB,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,aAAa;IACzB,OAAO,GAAG,iBAAiB,EAAE,IAAI,CAAC;AACtC,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { type OutputFormat } from './formats.js';
2
+ export interface DefaultOutputInputs {
3
+ /** Original input argument: file path or `-` for stdin. */
4
+ inputArg: string;
5
+ /** True when input is `-` (stdin). */
6
+ isStdin: boolean;
7
+ /** Resolved output format. */
8
+ format: OutputFormat;
9
+ /** Current working directory; defaults to `process.cwd()`. */
10
+ cwd?: string;
11
+ }
12
+ /**
13
+ * Resolves the default output path for render operations when `-o` is absent.
14
+ *
15
+ * Rules:
16
+ * - Default-named outputs land in **cwd**, never next to the input.
17
+ * - File input: `<cwd>/<input-base>.<format>` (input directory is ignored).
18
+ * - Stdin input: `<cwd>/roadmap.<format>`.
19
+ */
20
+ export declare function defaultRenderOutputPath(inputs: DefaultOutputInputs): string;
21
+ export interface InitOutputInputs {
22
+ /** Positional argument from `--init` (project name); undefined → default `roadmap`. */
23
+ name?: string;
24
+ /** Current working directory; defaults to `process.cwd()`. */
25
+ cwd?: string;
26
+ }
27
+ /**
28
+ * Resolves the output path for `--init`. The positional is treated as a project
29
+ * *name*, not a file path:
30
+ *
31
+ * - No extension (`my-project`) → append `.nowline`.
32
+ * - Already `.nowline` → use literal.
33
+ * - Other extension → caller should reject as a usage error (exit 2).
34
+ * - Missing → default name `roadmap`.
35
+ */
36
+ export declare function defaultInitOutputPath(inputs: InitOutputInputs): string;
37
+ /**
38
+ * Returns true when an `--init` positional has an extension other than
39
+ * `.nowline`. Caller should reject this with an exit-2 usage error.
40
+ */
41
+ export declare function initNameHasIncompatibleExtension(name: string): boolean;
42
+ /**
43
+ * Resolves the final output path for render operations, applying the
44
+ * extension-auto-add rule when `-o` is provided and has no extension.
45
+ */
46
+ export declare function resolveRenderOutputPath(args: {
47
+ outputArg: string | undefined;
48
+ isStdout: boolean;
49
+ inputArg: string;
50
+ isStdin: boolean;
51
+ format: OutputFormat;
52
+ cwd?: string;
53
+ }): {
54
+ path: string;
55
+ isStdout: boolean;
56
+ };
57
+ //# sourceMappingURL=output-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-path.d.ts","sourceRoot":"","sources":["../../src/cli/output-path.ts"],"names":[],"mappings":"AACA,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEvF,MAAM,WAAW,mBAAmB;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,EAAE,YAAY,CAAC;IACrB,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAQ3E;AAED,MAAM,WAAW,gBAAgB;IAC7B,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAQtE;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAmBtC"}
@@ -0,0 +1,70 @@
1
+ import * as path from 'node:path';
2
+ import { autoAddExtension, canonicalExtension } from './formats.js';
3
+ /**
4
+ * Resolves the default output path for render operations when `-o` is absent.
5
+ *
6
+ * Rules:
7
+ * - Default-named outputs land in **cwd**, never next to the input.
8
+ * - File input: `<cwd>/<input-base>.<format>` (input directory is ignored).
9
+ * - Stdin input: `<cwd>/roadmap.<format>`.
10
+ */
11
+ export function defaultRenderOutputPath(inputs) {
12
+ const cwd = inputs.cwd ?? process.cwd();
13
+ const ext = canonicalExtension(inputs.format);
14
+ if (inputs.isStdin) {
15
+ return path.join(cwd, `roadmap${ext}`);
16
+ }
17
+ const base = path.basename(inputs.inputArg, path.extname(inputs.inputArg)) || 'roadmap';
18
+ return path.join(cwd, `${base}${ext}`);
19
+ }
20
+ /**
21
+ * Resolves the output path for `--init`. The positional is treated as a project
22
+ * *name*, not a file path:
23
+ *
24
+ * - No extension (`my-project`) → append `.nowline`.
25
+ * - Already `.nowline` → use literal.
26
+ * - Other extension → caller should reject as a usage error (exit 2).
27
+ * - Missing → default name `roadmap`.
28
+ */
29
+ export function defaultInitOutputPath(inputs) {
30
+ const cwd = inputs.cwd ?? process.cwd();
31
+ const name = inputs.name ?? 'roadmap';
32
+ const ext = path.extname(name);
33
+ if (!ext) {
34
+ return path.join(cwd, `${name}.nowline`);
35
+ }
36
+ return path.join(cwd, name);
37
+ }
38
+ /**
39
+ * Returns true when an `--init` positional has an extension other than
40
+ * `.nowline`. Caller should reject this with an exit-2 usage error.
41
+ */
42
+ export function initNameHasIncompatibleExtension(name) {
43
+ const ext = path.extname(name).toLowerCase();
44
+ return ext !== '' && ext !== '.nowline';
45
+ }
46
+ /**
47
+ * Resolves the final output path for render operations, applying the
48
+ * extension-auto-add rule when `-o` is provided and has no extension.
49
+ */
50
+ export function resolveRenderOutputPath(args) {
51
+ if (args.isStdout) {
52
+ return { path: '-', isStdout: true };
53
+ }
54
+ if (args.outputArg !== undefined) {
55
+ return {
56
+ path: autoAddExtension(args.outputArg, args.format),
57
+ isStdout: false,
58
+ };
59
+ }
60
+ return {
61
+ path: defaultRenderOutputPath({
62
+ inputArg: args.inputArg,
63
+ isStdin: args.isStdin,
64
+ format: args.format,
65
+ cwd: args.cwd,
66
+ }),
67
+ isStdout: false,
68
+ };
69
+ }
70
+ //# sourceMappingURL=output-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-path.js","sourceRoot":"","sources":["../../src/cli/output-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAqB,MAAM,cAAc,CAAC;AAavF;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAA2B;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACxC,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;IACxF,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC;AAC3C,CAAC;AASD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAwB;IAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,UAAU,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gCAAgC,CAAC,IAAY;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,OAAO,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,UAAU,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAOvC;IACG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO;YACH,IAAI,EAAE,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;YACnD,QAAQ,EAAE,KAAK;SAClB,CAAC;IACN,CAAC;IACD,OAAO;QACH,IAAI,EAAE,uBAAuB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;SAChB,CAAC;QACF,QAAQ,EAAE,KAAK;KAClB,CAAC;AACN,CAAC"}