@zenithbuild/cli 0.6.6 → 0.6.9

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 (43) hide show
  1. package/dist/build.d.ts +32 -0
  2. package/dist/build.js +193 -548
  3. package/dist/compiler-bridge-runner.d.ts +5 -0
  4. package/dist/compiler-bridge-runner.js +70 -0
  5. package/dist/component-instance-ir.d.ts +6 -0
  6. package/dist/component-instance-ir.js +0 -20
  7. package/dist/component-occurrences.d.ts +6 -0
  8. package/dist/component-occurrences.js +6 -28
  9. package/dist/dev-server.d.ts +18 -0
  10. package/dist/dev-server.js +65 -114
  11. package/dist/dev-watch.d.ts +1 -0
  12. package/dist/dev-watch.js +2 -2
  13. package/dist/index.d.ts +8 -0
  14. package/dist/index.js +6 -28
  15. package/dist/manifest.d.ts +23 -0
  16. package/dist/manifest.js +22 -48
  17. package/dist/preview.d.ts +100 -0
  18. package/dist/preview.js +418 -488
  19. package/dist/resolve-components.d.ts +39 -0
  20. package/dist/resolve-components.js +30 -104
  21. package/dist/server/resolve-request-route.d.ts +39 -0
  22. package/dist/server/resolve-request-route.js +104 -113
  23. package/dist/server-contract.d.ts +39 -0
  24. package/dist/server-contract.js +15 -67
  25. package/dist/toolchain-paths.d.ts +23 -0
  26. package/dist/toolchain-paths.js +139 -39
  27. package/dist/toolchain-runner.d.ts +33 -0
  28. package/dist/toolchain-runner.js +194 -0
  29. package/dist/types/generate-env-dts.d.ts +5 -0
  30. package/dist/types/generate-env-dts.js +4 -2
  31. package/dist/types/generate-routes-dts.d.ts +8 -0
  32. package/dist/types/generate-routes-dts.js +7 -5
  33. package/dist/types/index.d.ts +14 -0
  34. package/dist/types/index.js +16 -7
  35. package/dist/ui/env.d.ts +18 -0
  36. package/dist/ui/env.js +0 -12
  37. package/dist/ui/format.d.ts +33 -0
  38. package/dist/ui/format.js +8 -46
  39. package/dist/ui/logger.d.ts +59 -0
  40. package/dist/ui/logger.js +3 -32
  41. package/dist/version-check.d.ts +54 -0
  42. package/dist/version-check.js +41 -98
  43. package/package.json +6 -4
@@ -0,0 +1,33 @@
1
+ import pc from 'picocolors';
2
+ import type { UiMode } from './env.js';
3
+ type FormatTag = keyof typeof TAG_COLORS | string;
4
+ interface SummaryRow {
5
+ label?: unknown;
6
+ value?: unknown;
7
+ }
8
+ declare const TAG_COLORS: {
9
+ DEV: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
10
+ BUILD: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
11
+ HMR: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
12
+ ROUTER: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
13
+ CSS: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
14
+ OK: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
15
+ WARN: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
16
+ ERR: (colors: ReturnType<typeof pc.createColors>, value: string) => string;
17
+ };
18
+ export declare function formatPrefix(mode: UiMode): string;
19
+ export declare function formatLine(mode: UiMode, { glyph, tag, text }: {
20
+ glyph?: string;
21
+ tag?: FormatTag;
22
+ text?: unknown;
23
+ }): string;
24
+ export declare function formatStep(mode: UiMode, text: unknown, tag?: FormatTag): string;
25
+ export declare function formatHint(mode: UiMode, text: unknown): string;
26
+ export declare function formatHeading(mode: UiMode, text: unknown): string;
27
+ export declare function formatSummaryTable(mode: UiMode, rows: SummaryRow[], tag?: FormatTag): string;
28
+ export declare function sanitizeErrorMessage(input: unknown): string;
29
+ export declare function normalizeErrorMessagePaths(message: string): string;
30
+ export declare function normalizeError(err: unknown): Error;
31
+ export declare function formatErrorBlock(err: unknown, mode: UiMode): string;
32
+ export declare function containsAnsi(value: unknown): boolean;
33
+ export {};
package/dist/ui/format.js CHANGED
@@ -1,12 +1,10 @@
1
1
  import pc from 'picocolors';
2
2
  import { relative, sep } from 'node:path';
3
-
4
3
  const DEFAULT_PHASE = 'cli';
5
4
  const DEFAULT_FILE = '.';
6
- const DEFAULT_HINT_BASE = 'https://github.com/zenithbuild/zenith/blob/main/zenith-cli/CLI_CONTRACT.md';
5
+ const DEFAULT_HINT_BASE = 'https://github.com/zenithbuild/framework/blob/master/packages/cli/CLI_CONTRACT.md';
7
6
  const PREFIX = '[zenith]';
8
7
  const TAG_WIDTH = 6;
9
-
10
8
  const TAG_COLORS = {
11
9
  DEV: (colors, value) => colors.cyan(value),
12
10
  BUILD: (colors, value) => colors.blue(value),
@@ -17,15 +15,12 @@ const TAG_COLORS = {
17
15
  WARN: (colors, value) => colors.bold(colors.yellow(value)),
18
16
  ERR: (colors, value) => colors.bold(colors.red(value))
19
17
  };
20
-
21
18
  function getColors(mode) {
22
- return pc.createColors(Boolean(mode?.color));
19
+ return pc.createColors(Boolean(mode.color));
23
20
  }
24
-
25
21
  export function formatPrefix(mode) {
26
22
  return mode.color ? getColors(mode).dim(PREFIX) : PREFIX;
27
23
  }
28
-
29
24
  function colorizeTag(mode, tag) {
30
25
  const padded = String(tag || '').padEnd(TAG_WIDTH, ' ');
31
26
  if (!mode.color) {
@@ -35,7 +30,6 @@ function colorizeTag(mode, tag) {
35
30
  const colorizer = TAG_COLORS[tag] || ((_colors, value) => colors.white(value));
36
31
  return colorizer(colors, padded);
37
32
  }
38
-
39
33
  function colorizeGlyph(mode, glyph, tag) {
40
34
  if (!mode.color) {
41
35
  return glyph;
@@ -44,56 +38,47 @@ function colorizeGlyph(mode, glyph, tag) {
44
38
  const colorizer = TAG_COLORS[tag] || ((_colors, value) => value);
45
39
  return colorizer(colors, glyph);
46
40
  }
47
-
48
41
  export function formatLine(mode, { glyph = '•', tag = 'DEV', text = '' }) {
49
42
  return `${formatPrefix(mode)} ${colorizeGlyph(mode, glyph, tag)} ${colorizeTag(mode, tag)} ${String(text || '')}`;
50
43
  }
51
-
52
44
  export function formatStep(mode, text, tag = 'BUILD') {
53
45
  return formatLine(mode, { glyph: '•', tag, text });
54
46
  }
55
-
56
47
  export function formatHint(mode, text) {
57
48
  const body = ` hint: ${String(text || '').trim()}`;
58
49
  return mode.color ? getColors(mode).dim(body) : body;
59
50
  }
60
-
61
51
  export function formatHeading(mode, text) {
62
52
  const label = mode.color ? getColors(mode).bold('Zenith CLI') : 'Zenith CLI';
63
53
  return `${label} ${String(text || '').trim()}`.trim();
64
54
  }
65
-
66
55
  export function formatSummaryTable(mode, rows, tag = 'BUILD') {
67
56
  if (!Array.isArray(rows) || rows.length === 0) {
68
57
  return '';
69
58
  }
70
59
  return rows
71
60
  .map((row) => formatLine(mode, {
72
- glyph: '•',
73
- tag,
74
- text: `${String(row.label || '')}: ${String(row.value || '')}`
75
- }))
61
+ glyph: '•',
62
+ tag,
63
+ text: `${String(row.label || '')}: ${String(row.value || '')}`
64
+ }))
76
65
  .join('\n');
77
66
  }
78
-
79
67
  export function sanitizeErrorMessage(input) {
80
68
  return String(input ?? '')
81
69
  .replace(/\r/g, '')
82
70
  .trim();
83
71
  }
84
-
85
72
  function normalizeFileLinePath(line) {
86
73
  const match = line.match(/^(\s*File:\s+)(.+)$/);
87
74
  if (!match) {
88
75
  return line;
89
76
  }
90
-
91
77
  const prefix = match[1];
92
78
  const filePath = match[2].trim();
93
79
  const normalized = normalizePathForDisplay(filePath);
94
80
  return `${prefix}${normalized}`;
95
81
  }
96
-
97
82
  function normalizePathForDisplay(filePath) {
98
83
  const value = String(filePath || '').trim();
99
84
  if (!value) {
@@ -102,7 +87,6 @@ function normalizePathForDisplay(filePath) {
102
87
  if (!value.startsWith('/') && !/^[A-Za-z]:\\/.test(value)) {
103
88
  return value;
104
89
  }
105
-
106
90
  const cwd = process.cwd();
107
91
  const cwdWithSep = cwd.endsWith(sep) ? cwd : `${cwd}${sep}`;
108
92
  if (value === cwd) {
@@ -112,10 +96,8 @@ function normalizePathForDisplay(filePath) {
112
96
  const relativePath = relative(cwd, value).replaceAll('\\', '/');
113
97
  return relativePath || DEFAULT_FILE;
114
98
  }
115
-
116
99
  return value;
117
100
  }
118
-
119
101
  function inferPhaseFromArgv() {
120
102
  const knownPhases = new Set(['build', 'dev', 'preview']);
121
103
  for (const arg of process.argv.slice(2)) {
@@ -125,12 +107,10 @@ function inferPhaseFromArgv() {
125
107
  }
126
108
  return DEFAULT_PHASE;
127
109
  }
128
-
129
110
  function extractFileFromMessage(message) {
130
111
  const match = String(message || '').match(/\bFile:\s+([^\n]+)/);
131
112
  return match ? match[1].trim() : '';
132
113
  }
133
-
134
114
  function formatHintUrl(code) {
135
115
  const slug = String(code || 'CLI_ERROR')
136
116
  .toLowerCase()
@@ -138,38 +118,27 @@ function formatHintUrl(code) {
138
118
  .replace(/^-+|-+$/g, '');
139
119
  return `${DEFAULT_HINT_BASE}#${slug || 'cli-error'}`;
140
120
  }
141
-
142
121
  export function normalizeErrorMessagePaths(message) {
143
122
  return String(message || '')
144
123
  .split('\n')
145
124
  .map((line) => normalizeFileLinePath(line))
146
125
  .join('\n');
147
126
  }
148
-
149
- /**
150
- * @param {unknown} err
151
- */
152
127
  export function normalizeError(err) {
153
128
  if (err instanceof Error) {
154
129
  return err;
155
130
  }
156
131
  return new Error(sanitizeErrorMessage(err));
157
132
  }
158
-
159
133
  function firstMeaningfulLine(text) {
160
134
  return String(text || '')
161
135
  .split('\n')
162
136
  .map((line) => line.trim())
163
137
  .find((line) => line.length > 0) || '';
164
138
  }
165
-
166
- /**
167
- * @param {unknown} err
168
- * @param {{ plain: boolean, color: boolean, debug?: boolean, logLevel?: string }} mode
169
- */
170
139
  export function formatErrorBlock(err, mode) {
171
140
  const normalized = normalizeError(err);
172
- const maybe = /** @type {{ code?: unknown, phase?: unknown, kind?: unknown, file?: unknown, hint?: unknown }} */ (normalized);
141
+ const maybe = normalized;
173
142
  const phase = maybe.phase ? sanitizeErrorMessage(maybe.phase) : inferPhaseFromArgv();
174
143
  const code = maybe.code
175
144
  ? sanitizeErrorMessage(maybe.code)
@@ -177,18 +146,14 @@ export function formatErrorBlock(err, mode) {
177
146
  const rawMessage = sanitizeErrorMessage(normalized.message || String(normalized));
178
147
  const message = normalizeErrorMessagePaths(rawMessage);
179
148
  const compactMessage = firstMeaningfulLine(message) || 'Command failed';
180
- const file = normalizePathForDisplay(
181
- sanitizeErrorMessage(maybe.file || extractFileFromMessage(message) || DEFAULT_FILE)
182
- );
149
+ const file = normalizePathForDisplay(sanitizeErrorMessage(maybe.file || extractFileFromMessage(message) || DEFAULT_FILE));
183
150
  const hint = sanitizeErrorMessage(maybe.hint || formatHintUrl(code));
184
-
185
151
  if (mode.logLevel !== 'verbose' && !mode.debug) {
186
152
  return [
187
153
  formatLine(mode, { glyph: '✖', tag: 'ERR', text: compactMessage }),
188
154
  formatHint(mode, hint)
189
155
  ].join('\n');
190
156
  }
191
-
192
157
  const lines = [];
193
158
  lines.push(formatLine(mode, { glyph: '✖', tag: 'ERR', text: compactMessage }));
194
159
  lines.push(formatHint(mode, hint || formatHintUrl(code)));
@@ -196,15 +161,12 @@ export function formatErrorBlock(err, mode) {
196
161
  lines.push(`${formatPrefix(mode)} phase: ${phase || DEFAULT_PHASE}`);
197
162
  lines.push(`${formatPrefix(mode)} file: ${file || DEFAULT_FILE}`);
198
163
  lines.push(`${formatPrefix(mode)} detail: ${message}`);
199
-
200
164
  if (mode.debug && normalized.stack) {
201
165
  lines.push(`${formatPrefix(mode)} stack:`);
202
166
  lines.push(...String(normalized.stack).split('\n').slice(0, 20));
203
167
  }
204
-
205
168
  return lines.join('\n');
206
169
  }
207
-
208
170
  export function containsAnsi(value) {
209
171
  return /\x1b\[[0-9;]*m/.test(String(value || ''));
210
172
  }
@@ -0,0 +1,59 @@
1
+ import { type UiMode, type UiRuntime } from './env.js';
2
+ type LoggerTag = 'DEV' | 'BUILD' | 'HMR' | 'ROUTER' | 'CSS' | 'OK' | 'WARN' | 'ERR' | string;
3
+ type LoggerStream = 'stdout' | 'stderr';
4
+ interface LoggerRuntime extends UiRuntime {
5
+ stdout: {
6
+ isTTY?: boolean;
7
+ write: (value: string) => void;
8
+ };
9
+ stderr: {
10
+ isTTY?: boolean;
11
+ write: (value: string) => void;
12
+ };
13
+ }
14
+ interface Spinner {
15
+ start(): void;
16
+ update(): void;
17
+ stop(): void;
18
+ succeed(): void;
19
+ fail(): void;
20
+ }
21
+ interface SummaryRow {
22
+ label?: unknown;
23
+ value?: unknown;
24
+ }
25
+ interface EmitOptions {
26
+ onceKey?: string;
27
+ hint?: string;
28
+ stream?: LoggerStream;
29
+ showInfo?: boolean;
30
+ prefix?: string;
31
+ error?: unknown;
32
+ }
33
+ export interface ZenithLogger {
34
+ mode: UiMode;
35
+ spinner: Spinner;
36
+ heading(text: string): void;
37
+ print(text: string): void;
38
+ summary(rows: SummaryRow[], tag?: LoggerTag): void;
39
+ dev(message: string, options?: EmitOptions): boolean;
40
+ build(message: string, options?: EmitOptions): boolean;
41
+ hmr(message: string, options?: EmitOptions): boolean;
42
+ router(message: string, options?: EmitOptions): boolean;
43
+ css(message: string, options?: EmitOptions): boolean;
44
+ ok(message: string, options?: EmitOptions): boolean;
45
+ warn(message: string, options?: EmitOptions): boolean;
46
+ error(messageOrError: unknown, options?: EmitOptions): boolean;
47
+ verbose(tag: LoggerTag, message: string, options?: EmitOptions): boolean;
48
+ childLine(source: string, line: string, options?: EmitOptions): boolean;
49
+ info(message: string): boolean;
50
+ success(message: string): boolean;
51
+ }
52
+ export declare function createZenithLogger(runtime?: LoggerRuntime, options?: {
53
+ logLevel?: string;
54
+ }): ZenithLogger;
55
+ export declare function createSilentLogger(): ZenithLogger;
56
+ export declare function createLogger(runtime?: LoggerRuntime, options?: {
57
+ logLevel?: string;
58
+ }): ZenithLogger;
59
+ export {};
package/dist/ui/logger.js CHANGED
@@ -1,16 +1,8 @@
1
- import {
2
- formatErrorBlock,
3
- formatHeading,
4
- formatHint,
5
- formatLine,
6
- formatSummaryTable
7
- } from './format.js';
1
+ import { formatErrorBlock, formatHeading, formatHint, formatLine, formatSummaryTable } from './format.js';
8
2
  import { getUiMode } from './env.js';
9
-
10
3
  function write(out, text) {
11
4
  out.write(`${text}\n`);
12
5
  }
13
-
14
6
  const SILENT_MODE = {
15
7
  plain: true,
16
8
  color: false,
@@ -20,7 +12,6 @@ const SILENT_MODE = {
20
12
  debug: false,
21
13
  logLevel: 'quiet'
22
14
  };
23
-
24
15
  function createNoopSpinner() {
25
16
  return {
26
17
  start() { },
@@ -30,11 +21,9 @@ function createNoopSpinner() {
30
21
  fail() { }
31
22
  };
32
23
  }
33
-
34
24
  function normalizeLevel(level) {
35
25
  return level === 'quiet' || level === 'verbose' ? level : 'normal';
36
26
  }
37
-
38
27
  function shouldEmit(mode, tag) {
39
28
  const level = normalizeLevel(mode.logLevel);
40
29
  if (level === 'quiet') {
@@ -42,7 +31,6 @@ function shouldEmit(mode, tag) {
42
31
  }
43
32
  return true;
44
33
  }
45
-
46
34
  function createWriter(runtime, mode, sink = null) {
47
35
  if (typeof sink === 'function') {
48
36
  return sink;
@@ -52,13 +40,11 @@ function createWriter(runtime, mode, sink = null) {
52
40
  write(out, text);
53
41
  };
54
42
  }
55
-
56
43
  function classifyChildLine(line) {
57
44
  const trimmed = String(line || '').trim();
58
45
  if (!trimmed) {
59
46
  return null;
60
47
  }
61
-
62
48
  const vendorCache = trimmed.match(/^\[zenith\]\s+Vendor cache (hit|miss):\s+(.+)$/);
63
49
  if (vendorCache) {
64
50
  return {
@@ -68,7 +54,6 @@ function classifyChildLine(line) {
68
54
  onceKey: `vendor-cache:${vendorCache[1]}:${vendorCache[2]}`
69
55
  };
70
56
  }
71
-
72
57
  const vendorBundle = trimmed.match(/^\[zenith\]\s+Vendor bundle:\s+(.+)$/);
73
58
  if (vendorBundle) {
74
59
  return {
@@ -78,7 +63,6 @@ function classifyChildLine(line) {
78
63
  onceKey: `vendor-bundle:${vendorBundle[1]}`
79
64
  };
80
65
  }
81
-
82
66
  const bundler = trimmed.match(/^\[zenith-bundler\]\s*(.+)$/);
83
67
  if (bundler) {
84
68
  const message = bundler[1].trim();
@@ -104,7 +88,6 @@ function classifyChildLine(line) {
104
88
  message
105
89
  };
106
90
  }
107
-
108
91
  const zenith = trimmed.match(/^\[zenith\]\s+(.+)$/);
109
92
  if (zenith) {
110
93
  return {
@@ -114,7 +97,6 @@ function classifyChildLine(line) {
114
97
  onceKey: `zenith-child:${zenith[1].trim()}`
115
98
  };
116
99
  }
117
-
118
100
  const compilerWarning = trimmed.match(/warning\[[^\]]+\]/i);
119
101
  if (compilerWarning) {
120
102
  return {
@@ -124,19 +106,16 @@ function classifyChildLine(line) {
124
106
  onceKey: `compiler-warning:${trimmed}`
125
107
  };
126
108
  }
127
-
128
109
  return {
129
110
  tag: 'BUILD',
130
111
  glyph: '•',
131
112
  message: trimmed
132
113
  };
133
114
  }
134
-
135
115
  function createBaseLogger({ runtime = process, mode, sink = null, silent = false } = {}) {
136
116
  const resolvedMode = mode || (silent ? SILENT_MODE : getUiMode(runtime));
137
117
  const once = new Set();
138
118
  const writeLine = createWriter(runtime, resolvedMode, sink);
139
-
140
119
  function emit(tag, glyph, message, options = {}) {
141
120
  if (options.onceKey) {
142
121
  if (once.has(options.onceKey)) {
@@ -144,11 +123,9 @@ function createBaseLogger({ runtime = process, mode, sink = null, silent = false
144
123
  }
145
124
  once.add(options.onceKey);
146
125
  }
147
-
148
126
  if (!shouldEmit(resolvedMode, tag)) {
149
127
  return false;
150
128
  }
151
-
152
129
  const stream = tag === 'WARN' || tag === 'ERR' ? 'stderr' : 'stdout';
153
130
  writeLine(stream, formatLine(resolvedMode, { glyph, tag, text: message }));
154
131
  if (options.hint) {
@@ -156,7 +133,6 @@ function createBaseLogger({ runtime = process, mode, sink = null, silent = false
156
133
  }
157
134
  return true;
158
135
  }
159
-
160
136
  return {
161
137
  mode: resolvedMode,
162
138
  spinner: createNoopSpinner(),
@@ -218,12 +194,11 @@ function createBaseLogger({ runtime = process, mode, sink = null, silent = false
218
194
  }
219
195
  return emit(tag, '•', message, options);
220
196
  },
221
- childLine(source, line, options = {}) {
197
+ childLine(_source, line, options = {}) {
222
198
  const entry = classifyChildLine(line);
223
199
  if (!entry) {
224
200
  return false;
225
201
  }
226
- const streamHint = options.stream === 'stderr';
227
202
  const isVerbose = resolvedMode.logLevel === 'verbose';
228
203
  const isSeverity = entry.tag === 'WARN' || entry.tag === 'ERR';
229
204
  if (!isVerbose && !isSeverity && options.showInfo === false) {
@@ -236,8 +211,7 @@ function createBaseLogger({ runtime = process, mode, sink = null, silent = false
236
211
  return emit(entry.tag, entry.glyph, message, {
237
212
  ...options,
238
213
  onceKey,
239
- hint: options.hint,
240
- stream: streamHint ? 'stderr' : undefined
214
+ hint: options.hint
241
215
  });
242
216
  },
243
217
  info(message) {
@@ -248,7 +222,6 @@ function createBaseLogger({ runtime = process, mode, sink = null, silent = false
248
222
  }
249
223
  };
250
224
  }
251
-
252
225
  export function createZenithLogger(runtime = process, options = {}) {
253
226
  const mode = getUiMode(runtime);
254
227
  if (options.logLevel) {
@@ -256,7 +229,6 @@ export function createZenithLogger(runtime = process, options = {}) {
256
229
  }
257
230
  return createBaseLogger({ runtime, mode });
258
231
  }
259
-
260
232
  export function createSilentLogger() {
261
233
  return createBaseLogger({
262
234
  mode: SILENT_MODE,
@@ -264,7 +236,6 @@ export function createSilentLogger() {
264
236
  silent: true
265
237
  });
266
238
  }
267
-
268
239
  export function createLogger(runtime = process, options = {}) {
269
240
  return createZenithLogger(runtime, options);
270
241
  }
@@ -0,0 +1,54 @@
1
+ type PackageKey = 'core' | 'compiler' | 'runtime' | 'router' | 'bundlerPackage';
2
+ type CompatibilityStatus = 'ok' | 'warn';
3
+ interface BundlerVersionResult {
4
+ version: string | null;
5
+ path: string;
6
+ rawOutput: string;
7
+ ok: boolean;
8
+ }
9
+ interface VersionIssue {
10
+ code: string;
11
+ summary: string;
12
+ message: string;
13
+ hint: string;
14
+ fixCommand: string;
15
+ }
16
+ export type ZenithVersions = Record<PackageKey, string | null> & {
17
+ cli: string;
18
+ projectCli: string | null;
19
+ bundlerBinary: string | null;
20
+ bundlerBinPath: string;
21
+ bundlerBinRawOutput: string;
22
+ targetVersion: string | null;
23
+ projectRoot?: string | null;
24
+ };
25
+ interface CompatibilityResult {
26
+ status: CompatibilityStatus;
27
+ issues: VersionIssue[];
28
+ details: {
29
+ targetVersion: string;
30
+ versions: Record<string, unknown>;
31
+ summary: string;
32
+ };
33
+ }
34
+ interface VersionCheckLogger {
35
+ warn: (message: string, options?: {
36
+ onceKey?: string;
37
+ hint?: string;
38
+ }) => void;
39
+ verbose: (tag: string, message: string) => void;
40
+ }
41
+ export declare function compareVersions(leftVersion: string | null | undefined, rightVersion: string | null | undefined): number;
42
+ export declare function getBundlerVersion(bundlerBinPath: string | null | undefined): BundlerVersionResult;
43
+ export declare function getLocalZenithVersions({ projectRoot, bundlerBinPath }?: {
44
+ projectRoot?: string | null;
45
+ bundlerBinPath?: string | null;
46
+ }): ZenithVersions;
47
+ export declare function checkCompatibility(versions: Partial<ZenithVersions>): CompatibilityResult;
48
+ export declare function maybeWarnAboutZenithVersionMismatch({ projectRoot, logger, command, bundlerBinPath }?: {
49
+ projectRoot?: string | null;
50
+ logger?: VersionCheckLogger | null;
51
+ command?: string;
52
+ bundlerBinPath?: string | null;
53
+ }): Promise<CompatibilityResult>;
54
+ export {};