@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,109 @@
1
+ export function adaptLangiumDiagnostic(diag, file) {
2
+ const severity = mapSeverity(diag.severity);
3
+ const line = (diag.range?.start.line ?? 0) + 1;
4
+ const column = (diag.range?.start.character ?? 0) + 1;
5
+ const data = extractMessageData(diag.data);
6
+ return {
7
+ file,
8
+ line,
9
+ column,
10
+ severity,
11
+ // Localized validator data carries the stable message code; prefer it
12
+ // over the heuristic message-substring inference below.
13
+ code: data?.code ?? diagnosticCode(diag),
14
+ message: diag.message,
15
+ span: diag.range
16
+ ? {
17
+ start: { line, column },
18
+ end: {
19
+ line: (diag.range.end.line ?? 0) + 1,
20
+ column: (diag.range.end.character ?? 0) + 1,
21
+ },
22
+ }
23
+ : undefined,
24
+ suggestion: extractSuggestion(diag.message),
25
+ data,
26
+ };
27
+ }
28
+ /**
29
+ * Validate the shape of `diag.data`. Validator-emitted diagnostics
30
+ * stash `{ code: MessageCode, args: MessageArgs<K> }` (where `args` is
31
+ * the spread tuple `[]` or `[{...}]`). Anything else (vscode code
32
+ * actions, third-party data, etc.) is ignored.
33
+ */
34
+ function extractMessageData(data) {
35
+ if (!data || typeof data !== 'object')
36
+ return undefined;
37
+ const obj = data;
38
+ if (typeof obj.code !== 'string')
39
+ return undefined;
40
+ if (!Array.isArray(obj.args))
41
+ return undefined;
42
+ return { code: obj.code, args: obj.args };
43
+ }
44
+ export function adaptParserError(err, file) {
45
+ const line = err.token?.startLine ?? 1;
46
+ const column = err.token?.startColumn ?? 1;
47
+ const endLine = err.token?.endLine ?? line;
48
+ const endColumn = (err.token?.endColumn ?? column) + 1;
49
+ return {
50
+ file,
51
+ line,
52
+ column,
53
+ severity: 'error',
54
+ code: 'parse-error',
55
+ message: err.message,
56
+ span: { start: { line, column }, end: { line: endLine, column: endColumn } },
57
+ };
58
+ }
59
+ export function adaptLexerError(err, file) {
60
+ const line = err.line ?? 1;
61
+ const column = err.column ?? 1;
62
+ const length = err.length ?? 1;
63
+ return {
64
+ file,
65
+ line,
66
+ column,
67
+ severity: 'error',
68
+ code: 'lex-error',
69
+ message: err.message,
70
+ span: {
71
+ start: { line, column },
72
+ end: { line, column: column + Math.max(length, 1) },
73
+ },
74
+ };
75
+ }
76
+ function mapSeverity(severity) {
77
+ return severity === 2 ? 'warning' : 'error';
78
+ }
79
+ function diagnosticCode(diag) {
80
+ if (typeof diag.code === 'string' && diag.code !== '')
81
+ return diag.code;
82
+ if (typeof diag.code === 'number')
83
+ return String(diag.code);
84
+ return inferCodeFromMessage(diag.message);
85
+ }
86
+ function inferCodeFromMessage(message) {
87
+ const lower = message.toLowerCase();
88
+ if (lower.includes('duplicate identifier'))
89
+ return 'duplicate-identifier';
90
+ if (lower.includes('unknown reference') || lower.includes('did you mean'))
91
+ return 'unknown-reference';
92
+ if (lower.includes('circular'))
93
+ return 'circular-dependency';
94
+ if (lower.includes('requires') && lower.includes('date:'))
95
+ return 'missing-date';
96
+ if (lower.includes('duration'))
97
+ return 'duration';
98
+ if (lower.includes('include'))
99
+ return 'include';
100
+ if (lower.includes('indent'))
101
+ return 'indentation';
102
+ return 'validation';
103
+ }
104
+ const DID_YOU_MEAN_RE = /did you mean ['"]?([^'"?]+)['"]?\??/i;
105
+ function extractSuggestion(message) {
106
+ const match = message.match(DID_YOU_MEAN_RE);
107
+ return match ? match[1].trim() : undefined;
108
+ }
109
+ //# sourceMappingURL=adapt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapt.js","sourceRoot":"","sources":["../../src/diagnostics/adapt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { CliDiagnostic, DiagnosticSource } from './model.js';
2
+ export type DiagnosticFormat = 'text' | 'json';
3
+ export interface FormatDiagnosticsOptions {
4
+ color?: boolean;
5
+ /**
6
+ * Operator locale (BCP-47) used to re-format validator messages
7
+ * that carry `data: { code, args }`. Validator messages without
8
+ * `data` and parser/lexer errors pass through unchanged.
9
+ *
10
+ * Defaults to en-US: an unset operator locale produces the same
11
+ * canonical English text the validator stashed at parse time.
12
+ * See `specs/localization.md` for the two-chain model.
13
+ */
14
+ operatorLocale?: string;
15
+ }
16
+ export declare function isDiagnosticFormat(value: unknown): value is DiagnosticFormat;
17
+ export declare function formatDiagnostics(diagnostics: CliDiagnostic[], format: DiagnosticFormat, sources: Map<string, DiagnosticSource>, options?: FormatDiagnosticsOptions): string;
18
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/diagnostics/format.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGlE,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,CAAC;AAE/C,MAAM,WAAW,wBAAwB;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAED,wBAAgB,iBAAiB,CAC7B,WAAW,EAAE,aAAa,EAAE,EAC5B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACtC,OAAO,GAAE,wBAA6B,GACvC,MAAM,CAIR"}
@@ -0,0 +1,41 @@
1
+ import { tr } from '@nowline/core';
2
+ import { renderJson } from './json.js';
3
+ import { renderText } from './text.js';
4
+ export function isDiagnosticFormat(value) {
5
+ return value === 'text' || value === 'json';
6
+ }
7
+ export function formatDiagnostics(diagnostics, format, sources, options = {}) {
8
+ const localized = relocalizeDiagnostics(diagnostics, options.operatorLocale);
9
+ if (format === 'json')
10
+ return renderJson(localized);
11
+ return renderText(localized, sources, { color: options.color });
12
+ }
13
+ /**
14
+ * Re-format any diagnostic carrying `data.{code,args}` in the operator
15
+ * locale. Diagnostics without `data` (literal-English validator
16
+ * strings, parser/lexer errors, include-resolution errors) pass
17
+ * through verbatim.
18
+ *
19
+ * No-op when `operatorLocale` is undefined or `'en-US'`: the messages
20
+ * stashed by the validator are already en-US, so we avoid the work
21
+ * and the allocation in the common case.
22
+ */
23
+ function relocalizeDiagnostics(diagnostics, operatorLocale) {
24
+ if (!operatorLocale || operatorLocale === 'en-US')
25
+ return diagnostics;
26
+ return diagnostics.map((d) => {
27
+ if (!d.data)
28
+ return d;
29
+ // The validator stashes args as the verbatim spread tuple it received,
30
+ // typed strongly per-code in `@nowline/core/i18n`. By the time it
31
+ // reaches us through `unknown` it has lost that tagged shape; we cast
32
+ // back here because the only producer is the validator and the
33
+ // `code` half of the pair pins the expected arity.
34
+ const args = d.data.args;
35
+ const message = tr(operatorLocale, d.data.code, ...args);
36
+ if (message === d.message)
37
+ return d;
38
+ return { ...d, message };
39
+ });
40
+ }
41
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/diagnostics/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,EAAE,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAkBvC,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC7C,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC7B,WAA4B,EAC5B,MAAwB,EACxB,OAAsC,EACtC,UAAoC,EAAE;IAEtC,MAAM,SAAS,GAAG,qBAAqB,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7E,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;IACpD,OAAO,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,qBAAqB,CAC1B,WAA4B,EAC5B,cAAkC;IAElC,IAAI,CAAC,cAAc,IAAI,cAAc,KAAK,OAAO;QAAE,OAAO,WAAW,CAAC;IACtE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACzB,IAAI,CAAC,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC;QACtB,uEAAuE;QACvE,kEAAkE;QAClE,sEAAsE;QACtE,+DAA+D;QAC/D,mDAAmD;QACnD,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAMT,CAAC;QACZ,MAAM,OAAO,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,IAAmB,EAAE,GAAG,IAAI,CAAC,CAAC;QACxE,IAAI,OAAO,KAAK,CAAC,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC;QACpC,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './adapt.js';
2
+ export * from './format.js';
3
+ export { DIAGNOSTICS_SCHEMA_VERSION, type DiagnosticsDocument } from './json.js';
4
+ export * from './model.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,0BAA0B,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACjF,cAAc,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './adapt.js';
2
+ export * from './format.js';
3
+ export { DIAGNOSTICS_SCHEMA_VERSION } from './json.js';
4
+ export * from './model.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,0BAA0B,EAA4B,MAAM,WAAW,CAAC;AACjF,cAAc,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { CliDiagnostic } from './model.js';
2
+ export declare const DIAGNOSTICS_SCHEMA_VERSION = "1";
3
+ export interface DiagnosticsDocument {
4
+ $nowlineDiagnostics: string;
5
+ diagnostics: CliDiagnostic[];
6
+ }
7
+ export declare function renderJson(diagnostics: CliDiagnostic[]): string;
8
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/diagnostics/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,aAAa,EAAE,GAAG,MAAM,CAM/D"}
@@ -0,0 +1,24 @@
1
+ export const DIAGNOSTICS_SCHEMA_VERSION = '1';
2
+ export function renderJson(diagnostics) {
3
+ const doc = {
4
+ $nowlineDiagnostics: DIAGNOSTICS_SCHEMA_VERSION,
5
+ diagnostics: diagnostics.map(normalize),
6
+ };
7
+ return JSON.stringify(doc, null, 2);
8
+ }
9
+ function normalize(d) {
10
+ const out = {
11
+ file: d.file,
12
+ line: d.line,
13
+ column: d.column,
14
+ severity: d.severity,
15
+ code: d.code,
16
+ message: d.message,
17
+ };
18
+ if (d.suggestion)
19
+ out.suggestion = d.suggestion;
20
+ if (d.span)
21
+ out.span = d.span;
22
+ return out;
23
+ }
24
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/diagnostics/json.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAO9C,MAAM,UAAU,UAAU,CAAC,WAA4B;IACnD,MAAM,GAAG,GAAwB;QAC7B,mBAAmB,EAAE,0BAA0B;QAC/C,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC;KAC1C,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,SAAS,CAAC,CAAgB;IAC/B,MAAM,GAAG,GAAkB;QACvB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,OAAO,EAAE,CAAC,CAAC,OAAO;KACrB,CAAC;IACF,IAAI,CAAC,CAAC,UAAU;QAAE,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IAChD,IAAI,CAAC,CAAC,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IAC9B,OAAO,GAAG,CAAC;AACf,CAAC"}
@@ -0,0 +1,44 @@
1
+ export type DiagnosticSeverity = 'error' | 'warning';
2
+ export interface SourcePosition {
3
+ line: number;
4
+ column: number;
5
+ offset?: number;
6
+ }
7
+ export interface SourceSpan {
8
+ start: SourcePosition;
9
+ end: SourcePosition;
10
+ }
11
+ /**
12
+ * Carries the validator's stable message code plus the named-argument
13
+ * record it was formatted from, so the CLI can re-format the human
14
+ * message in the operator's locale at print time. See
15
+ * `specs/localization.md` for the two-chain precedence model.
16
+ */
17
+ export interface LocalizedMessageData {
18
+ code: string;
19
+ args: ReadonlyArray<unknown>;
20
+ }
21
+ export interface CliDiagnostic {
22
+ file: string;
23
+ line: number;
24
+ column: number;
25
+ severity: DiagnosticSeverity;
26
+ code: string;
27
+ message: string;
28
+ suggestion?: string;
29
+ span?: SourceSpan;
30
+ /**
31
+ * Stable code + args as captured by the validator. Present on
32
+ * messages that flow through the `tr()` registry; absent for
33
+ * literal-English validator strings, parser/lexer errors, and
34
+ * include-resolution diagnostics. The CLI re-formats `message`
35
+ * from this when an operator locale is supplied to
36
+ * `formatDiagnostics`.
37
+ */
38
+ data?: LocalizedMessageData;
39
+ }
40
+ export interface DiagnosticSource {
41
+ file: string;
42
+ contents: string;
43
+ }
44
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/diagnostics/model.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,cAAc,CAAC;IACtB,GAAG,EAAE,cAAc,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/diagnostics/model.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { CliDiagnostic, DiagnosticSource } from './model.js';
2
+ export interface RenderTextOptions {
3
+ color?: boolean;
4
+ }
5
+ export declare function renderText(diagnostics: CliDiagnostic[], sources: Map<string, DiagnosticSource>, options?: RenderTextOptions): string;
6
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/diagnostics/text.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,WAAW,iBAAiB;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,UAAU,CACtB,WAAW,EAAE,aAAa,EAAE,EAC5B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACtC,OAAO,GAAE,iBAAsB,GAChC,MAAM,CAIR"}
@@ -0,0 +1,43 @@
1
+ import { codeFrameColumns } from '@babel/code-frame';
2
+ import chalk from 'chalk';
3
+ export function renderText(diagnostics, sources, options = {}) {
4
+ const useColor = options.color ?? chalk.level > 0;
5
+ const parts = diagnostics.map((d) => renderOne(d, sources.get(d.file), useColor));
6
+ return parts.join('\n\n');
7
+ }
8
+ function renderOne(diag, source, useColor) {
9
+ const header = renderHeader(diag, useColor);
10
+ if (!source)
11
+ return header;
12
+ const frame = codeFrameColumns(source.contents, {
13
+ start: { line: diag.line, column: diag.column },
14
+ end: diag.span ? { line: diag.span.end.line, column: diag.span.end.column } : undefined,
15
+ }, {
16
+ highlightCode: useColor,
17
+ linesAbove: 2,
18
+ linesBelow: 1,
19
+ forceColor: useColor,
20
+ });
21
+ return `${header}\n${frame}`;
22
+ }
23
+ function renderHeader(diag, useColor) {
24
+ const loc = `${diag.file}:${diag.line}:${diag.column}`;
25
+ const severityWord = diag.severity === 'error' ? 'error' : 'warning';
26
+ if (!useColor) {
27
+ const suffix = diag.suggestion ? ` — did you mean '${diag.suggestion}'?` : '';
28
+ return `${loc} ${severityWord}: ${stripSuggestion(diag.message, diag.suggestion)}${suffix}`;
29
+ }
30
+ const coloredLoc = chalk.cyan(loc);
31
+ const coloredSeverity = diag.severity === 'error' ? chalk.red.bold(severityWord) : chalk.yellow.bold(severityWord);
32
+ const message = stripSuggestion(diag.message, diag.suggestion);
33
+ const suggestion = diag.suggestion
34
+ ? ` ${chalk.dim('—')} did you mean ${chalk.green(`'${diag.suggestion}'`)}?`
35
+ : '';
36
+ return `${coloredLoc} ${coloredSeverity}: ${message}${suggestion}`;
37
+ }
38
+ function stripSuggestion(message, suggestion) {
39
+ if (!suggestion)
40
+ return message;
41
+ return message.replace(/ —\s*did you mean ['"]?[^'"?]+['"]?\??/i, '').trimEnd();
42
+ }
43
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/diagnostics/text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type TemplateName = 'minimal' | 'teams' | 'product';
2
+ export declare const TEMPLATE_NAMES: readonly TemplateName[];
3
+ export declare const TEMPLATES: Record<TemplateName, string>;
4
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/generated/templates.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3D,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAAoC,CAAC;AAEvF,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAIlD,CAAC"}
@@ -0,0 +1,9 @@
1
+ // Auto-generated by scripts/bundle-templates.mjs. Do not edit by hand.
2
+ // Run `pnpm run bundle-templates` to regenerate.
3
+ export const TEMPLATE_NAMES = ['minimal', 'teams', 'product'];
4
+ export const TEMPLATES = {
5
+ "minimal": "nowline v1\n\nroadmap minimal \"Starter\" start:2026-01-05 scale:2w author:\"Jane Doe\"\n\nswimlane engineering \"Engineering\"\n parallel concurrent-block style:concurrent\n group research-group \"Research\"\n item research \"Research\" duration:3w status:done\n item design \"Design\" duration:2w status:in-progress remaining:5d\n item build \"Build\" duration:3w status:planned\n group release-group \"Release\"\n item release \"Release\" duration:1w status:planned\n item deploy \"Deploy\" duration:1w status:planned\n",
6
+ "teams": "nowline v1\n\nroadmap teams-2026 \"Teams Roadmap 2026\" start:2026-01-05\n\nperson sam \"Sam Chen\" link:https://github.com/samchen\nperson jen \"Jennifer Wu\"\nperson alex \"Alex Rivera\"\n\nteam engineering \"Engineering\"\n team platform-team \"Platform Team\"\n person sam\n person jen\n team mobile-team \"Mobile Team\"\n person alex\n\nanchor kickoff date:2026-01-06\nanchor mid-year date:2026-07-01\nanchor eoy \"End of Year\" date:2026-12-15\n\nswimlane platform owner:platform-team\n item auth \"Auth refactor\" duration:1m after:kickoff owner:sam status:done\n item api-v2 \"API v2\" duration:2w owner:jen status:in-progress remaining:40%\n\nswimlane mobile owner:mobile-team\n item offline \"Offline mode\" duration:1m after:kickoff owner:alex status:at-risk remaining:60%\n item push \"Push notifications\" duration:2w owner:alex\n\nmilestone beta \"Beta\" after:[auth, api-v2]\nmilestone ga \"GA\" date:2026-12-01 after:[offline, push]\n\nfootnote eng-capacity \"Mobile team capacity risk\" on:mobile-team\n description \"Mobile team is understaffed through Q2.\"\n\nfootnote vendor-dep \"Vendor dependency\" on:[auth, api-v2]\n description \"Blocked until vendor contract is signed.\"\n",
7
+ "product": "nowline v1\n\nconfig\n\nscale\n name: weeks\n label-every: 2\n label: \"W{n}\"\n\ncalendar\n days-per-week: 5\n days-per-month: 22\n days-per-quarter: 65\n days-per-year: 260\n\nstyle enterprise-style \"Enterprise readiness\"\n bg: blue\n fg: navy\n text: white\n border: solid\n\nstyle risky\n border: dashed\n fg: orange\n\nstyle subtle\n bg: gray\n\ndefault item shadow:subtle\ndefault swimlane padding:sm spacing:none\ndefault roadmap padding:md header-height:md font:sans\ndefault parallel bracket:none\n\nroadmap platform-2026 \"Platform 2026\" author:\"Acme Engineering\" start:2026-01-05 calendar:custom\n\nperson sam \"Sam Chen\"\nperson jen \"Jennifer Wu\"\n\nsize xs effort:1d\nsize sm effort:3d\nsize md effort:1w\nsize lg effort:2w\nsize xl effort:1m\n\nstatus awaiting-review\nstatus in-review\n\nlabel enterprise \"Enterprise readiness\" style:enterprise-style\nlabel security \"Security hardening\" style:enterprise-style\nlabel low-confidence style:risky\n\nanchor kickoff date:2026-01-06\nanchor code-freeze \"Code Freeze\" date:2026-05-01\nanchor ga-date \"GA Date\" date:2026-06-01\n\nswimlane platform\n item auth-refactor \"Auth refactor\" size:lg after:kickoff status:done owner:sam labels:enterprise link:https://github.com/acme/platform/issues/123\n parallel after:auth-refactor\n group audit-track \"Audit Track\" labels:security\n item audit-log \"Audit log v2\" size:xl before:code-freeze remaining:30% labels:[enterprise, security]\n description \"Comprehensive audit trail for all admin actions\"\n item audit-ui \"Audit UI\" size:md\n item sso \"SSO plugins\" size:md labels:[enterprise, low-confidence]\n item platform-qa \"Platform QA\" size:sm\n\nswimlane mobile\n item offline \"Offline mode\" size:lg after:kickoff owner:jen status:at-risk remaining:60% link:https://github.com/acme/mobile/pull/87\n item push-v2 \"Push notifications v2\" size:md\n\nmilestone beta \"Beta\" after:auth-refactor\nmilestone ga-launch \"GA launch\" date:2026-06-01 after:[auth-refactor, audit-log]\n\nfootnote vendor-footnote \"Vendor dependency\" on:audit-log\n description \"Blocked until vendor contract is signed. Expected March resolution.\"\n"
8
+ };
9
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/generated/templates.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,iDAAiD;AAIjD,MAAM,CAAC,MAAM,cAAc,GAA4B,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAEvF,MAAM,CAAC,MAAM,SAAS,GAAiC;IACnD,SAAS,EAAE,ikBAAikB;IAC5kB,OAAO,EAAE,msCAAmsC;IAC5sC,SAAS,EAAE,iqEAAiqE;CAC/qE,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare const CLI_VERSION = "0.2.0";
2
+ export interface CliBuild {
3
+ /** Short git SHA at build time, or empty when not in a git checkout. */
4
+ readonly sha: string;
5
+ /** True when HEAD is the tag matching `v${CLI_VERSION}`. */
6
+ readonly isRelease: boolean;
7
+ /** True when the working tree had uncommitted changes at build time. */
8
+ readonly isDirty: boolean;
9
+ }
10
+ export declare const CLI_BUILD: CliBuild;
11
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/generated/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,MAAM,WAAW,QAAQ;IACrB,wEAAwE;IACxE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC7B;AAED,eAAO,MAAM,SAAS,EAAE,QAIvB,CAAC"}
@@ -0,0 +1,8 @@
1
+ // Auto-generated by scripts/bundle-templates.mjs. Do not edit by hand.
2
+ export const CLI_VERSION = "0.2.0";
3
+ export const CLI_BUILD = {
4
+ "sha": "c51e2a4",
5
+ "isRelease": true,
6
+ "isDirty": false
7
+ };
8
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/generated/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAWnC,MAAM,CAAC,MAAM,SAAS,GAAa;IAC/B,KAAK,EAAE,SAAS;IAChB,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,KAAK;CACnB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { NowlineFile } from '@nowline/core';
2
+ declare const ENV_VARS: readonly ["LC_ALL", "LC_MESSAGES", "LANG"];
3
+ type EnvVar = (typeof ENV_VARS)[number];
4
+ export type LocaleSource = 'flag' | 'env' | 'rc';
5
+ export interface ResolvedLocale {
6
+ /** BCP-47 tag, or undefined when no source produced one. */
7
+ tag: string | undefined;
8
+ /** Which input chain produced `tag`. Undefined iff `tag` is undefined. */
9
+ source: LocaleSource | undefined;
10
+ /** When `source === 'env'`, the specific variable that contributed. */
11
+ envVar?: EnvVar;
12
+ }
13
+ export interface ResolveLocaleInputs {
14
+ /** Value of the `--locale` flag, or undefined. */
15
+ flag: string | undefined;
16
+ /** Process environment, parameterized for testability. */
17
+ env: NodeJS.ProcessEnv;
18
+ /** Optional `.nowlinerc` `locale` key. Slots below env vars. */
19
+ rc?: string | undefined;
20
+ }
21
+ /**
22
+ * Resolve the operator's locale override.
23
+ *
24
+ * Precedence (highest wins): `--locale` flag > env vars > `.nowlinerc`.
25
+ * POSIX `C` / `POSIX` env values mean "no localization" and are skipped.
26
+ *
27
+ * Returns `{ tag: undefined, source: undefined }` when nothing is set —
28
+ * `operatorLocale` then defaults to `en-US`, while the layout's content
29
+ * chain falls back to whatever the file's `locale:` directive declares.
30
+ */
31
+ export declare function resolveLocaleOverride({ flag, env, rc }: ResolveLocaleInputs): ResolvedLocale;
32
+ /**
33
+ * Resolve the operator-facing locale used to format CLI message output.
34
+ * `en-US` when the operator has no signal in the environment.
35
+ */
36
+ export declare function operatorLocale(resolved: ResolvedLocale): string;
37
+ /**
38
+ * Describe which locale governs the rendered artifact and where the
39
+ * value came from. Used by the `--verbose` log line so an operator can
40
+ * see at a glance whether the file or the operator chain is winning.
41
+ *
42
+ * Precedence mirrors the layout's `resolveLocale`:
43
+ * file directive > CLI flag > env > `.nowlinerc` > en-US (default).
44
+ */
45
+ export declare function describeContentLocaleSource(directive: string | undefined, resolved: ResolvedLocale): {
46
+ tag: string;
47
+ source: string;
48
+ };
49
+ /**
50
+ * Read the optional `locale:` property from a parsed file's
51
+ * `nowline v1` directive. Returns undefined when the directive is
52
+ * absent, malformed, or omits the property.
53
+ */
54
+ export declare function readDirectiveLocale(file: NowlineFile | undefined): string | undefined;
55
+ export {};
56
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/i18n/locale.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAYjD,QAAA,MAAM,QAAQ,4CAA6C,CAAC;AAC5D,KAAK,MAAM,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAExC,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC3B,4DAA4D;IAC5D,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,0EAA0E;IAC1E,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;IACjC,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAChC,kDAAkD;IAClD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,0DAA0D;IAC1D,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,mBAAmB,GAAG,cAAc,CAe5F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAE/D;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACvC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,QAAQ,EAAE,cAAc,GACzB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAajC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrF"}
@@ -0,0 +1,107 @@
1
+ // Resolve the operator-locale override from CLI flag, environment, and
2
+ // `.nowlinerc`. See `specs/localization.md` for the two-chain model.
3
+ //
4
+ // Operator locale governs CLI message output: validator diagnostics on
5
+ // stderr, `--help`, format errors, verbose logs. It is independent from
6
+ // the file's `locale:` directive, which governs the rendered artifact.
7
+ //
8
+ // Returns the resolved tag plus the source it came from, so verbose
9
+ // logging can describe the chain without re-walking it.
10
+ const ENV_VARS = ['LC_ALL', 'LC_MESSAGES', 'LANG'];
11
+ /**
12
+ * Resolve the operator's locale override.
13
+ *
14
+ * Precedence (highest wins): `--locale` flag > env vars > `.nowlinerc`.
15
+ * POSIX `C` / `POSIX` env values mean "no localization" and are skipped.
16
+ *
17
+ * Returns `{ tag: undefined, source: undefined }` when nothing is set —
18
+ * `operatorLocale` then defaults to `en-US`, while the layout's content
19
+ * chain falls back to whatever the file's `locale:` directive declares.
20
+ */
21
+ export function resolveLocaleOverride({ flag, env, rc }) {
22
+ if (flag)
23
+ return { tag: flag, source: 'flag' };
24
+ for (const name of ENV_VARS) {
25
+ const raw = env[name];
26
+ if (!raw)
27
+ continue;
28
+ const stripped = stripPosixSuffix(raw);
29
+ if (!stripped || stripped === 'C' || stripped === 'POSIX') {
30
+ // POSIX `C` / `POSIX` locale means "no localization." Skip and
31
+ // let the next env var or the rc file take over.
32
+ continue;
33
+ }
34
+ return { tag: normalizePosixToBcp47(stripped), source: 'env', envVar: name };
35
+ }
36
+ if (rc)
37
+ return { tag: rc, source: 'rc' };
38
+ return { tag: undefined, source: undefined };
39
+ }
40
+ /**
41
+ * Resolve the operator-facing locale used to format CLI message output.
42
+ * `en-US` when the operator has no signal in the environment.
43
+ */
44
+ export function operatorLocale(resolved) {
45
+ return resolved.tag ?? 'en-US';
46
+ }
47
+ /**
48
+ * Describe which locale governs the rendered artifact and where the
49
+ * value came from. Used by the `--verbose` log line so an operator can
50
+ * see at a glance whether the file or the operator chain is winning.
51
+ *
52
+ * Precedence mirrors the layout's `resolveLocale`:
53
+ * file directive > CLI flag > env > `.nowlinerc` > en-US (default).
54
+ */
55
+ export function describeContentLocaleSource(directive, resolved) {
56
+ if (directive)
57
+ return { tag: directive, source: 'from file directive' };
58
+ if (resolved.tag === undefined)
59
+ return { tag: 'en-US', source: 'default' };
60
+ switch (resolved.source) {
61
+ case 'flag':
62
+ return { tag: resolved.tag, source: 'from --locale' };
63
+ case 'env':
64
+ return { tag: resolved.tag, source: `from ${resolved.envVar} env var` };
65
+ case 'rc':
66
+ return { tag: resolved.tag, source: 'from .nowlinerc' };
67
+ default:
68
+ return { tag: resolved.tag, source: 'from operator chain' };
69
+ }
70
+ }
71
+ /**
72
+ * Read the optional `locale:` property from a parsed file's
73
+ * `nowline v1` directive. Returns undefined when the directive is
74
+ * absent, malformed, or omits the property.
75
+ */
76
+ export function readDirectiveLocale(file) {
77
+ const prop = file?.directive?.properties.find((p) => stripColon(p.key) === 'locale');
78
+ return prop?.value || undefined;
79
+ }
80
+ function stripColon(key) {
81
+ return key.endsWith(':') ? key.slice(0, -1) : key;
82
+ }
83
+ /**
84
+ * POSIX `LANG` values look like `en_US.UTF-8` or `fr_CA@euro`. Strip
85
+ * everything from `.` or `@` onward — Nowline only cares about the
86
+ * language and region.
87
+ */
88
+ function stripPosixSuffix(value) {
89
+ const dot = value.indexOf('.');
90
+ const at = value.indexOf('@');
91
+ let end = value.length;
92
+ if (dot !== -1 && dot < end)
93
+ end = dot;
94
+ if (at !== -1 && at < end)
95
+ end = at;
96
+ return value.slice(0, end).trim();
97
+ }
98
+ /**
99
+ * Normalize `fr_CA` to `fr-CA`. POSIX uses `_`; BCP-47 uses `-`.
100
+ * Casing follows BCP-47 conventions: language lowercase, region
101
+ * uppercase 2-letter, but the layout's BCP-47 walker normalizes again
102
+ * defensively, so this is best-effort.
103
+ */
104
+ function normalizePosixToBcp47(value) {
105
+ return value.replace('_', '-');
106
+ }
107
+ //# sourceMappingURL=locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/i18n/locale.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}