@agentuity/cli 0.0.42 → 0.0.43

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 (101) hide show
  1. package/bin/cli.ts +7 -5
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cmd/auth/index.d.ts.map +1 -1
  4. package/dist/cmd/auth/whoami.d.ts +2 -0
  5. package/dist/cmd/auth/whoami.d.ts.map +1 -0
  6. package/dist/cmd/bundle/index.d.ts +1 -1
  7. package/dist/cmd/bundle/index.d.ts.map +1 -1
  8. package/dist/cmd/cloud/deploy.d.ts +2 -0
  9. package/dist/cmd/cloud/deploy.d.ts.map +1 -0
  10. package/dist/cmd/cloud/index.d.ts +2 -0
  11. package/dist/cmd/cloud/index.d.ts.map +1 -0
  12. package/dist/cmd/dev/index.d.ts.map +1 -1
  13. package/dist/cmd/env/delete.d.ts +2 -0
  14. package/dist/cmd/env/delete.d.ts.map +1 -0
  15. package/dist/cmd/env/get.d.ts +2 -0
  16. package/dist/cmd/env/get.d.ts.map +1 -0
  17. package/dist/cmd/env/import.d.ts +2 -0
  18. package/dist/cmd/env/import.d.ts.map +1 -0
  19. package/dist/cmd/env/index.d.ts +2 -0
  20. package/dist/cmd/env/index.d.ts.map +1 -0
  21. package/dist/cmd/env/list.d.ts +2 -0
  22. package/dist/cmd/env/list.d.ts.map +1 -0
  23. package/dist/cmd/env/pull.d.ts +2 -0
  24. package/dist/cmd/env/pull.d.ts.map +1 -0
  25. package/dist/cmd/env/push.d.ts +2 -0
  26. package/dist/cmd/env/push.d.ts.map +1 -0
  27. package/dist/cmd/env/set.d.ts +2 -0
  28. package/dist/cmd/env/set.d.ts.map +1 -0
  29. package/dist/cmd/project/download.d.ts +1 -1
  30. package/dist/cmd/project/download.d.ts.map +1 -1
  31. package/dist/cmd/project/template-flow.d.ts +1 -1
  32. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  33. package/dist/cmd/secret/delete.d.ts +2 -0
  34. package/dist/cmd/secret/delete.d.ts.map +1 -0
  35. package/dist/cmd/secret/get.d.ts +2 -0
  36. package/dist/cmd/secret/get.d.ts.map +1 -0
  37. package/dist/cmd/secret/import.d.ts +2 -0
  38. package/dist/cmd/secret/import.d.ts.map +1 -0
  39. package/dist/cmd/secret/index.d.ts +2 -0
  40. package/dist/cmd/secret/index.d.ts.map +1 -0
  41. package/dist/cmd/secret/list.d.ts +2 -0
  42. package/dist/cmd/secret/list.d.ts.map +1 -0
  43. package/dist/cmd/secret/pull.d.ts +2 -0
  44. package/dist/cmd/secret/pull.d.ts.map +1 -0
  45. package/dist/cmd/secret/push.d.ts +2 -0
  46. package/dist/cmd/secret/push.d.ts.map +1 -0
  47. package/dist/cmd/secret/set.d.ts +2 -0
  48. package/dist/cmd/secret/set.d.ts.map +1 -0
  49. package/dist/cmd/version/index.d.ts.map +1 -1
  50. package/dist/config.d.ts +2 -0
  51. package/dist/config.d.ts.map +1 -1
  52. package/dist/env-util.d.ts +67 -0
  53. package/dist/env-util.d.ts.map +1 -0
  54. package/dist/env-util.test.d.ts +2 -0
  55. package/dist/env-util.test.d.ts.map +1 -0
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/schema-parser.d.ts.map +1 -1
  59. package/dist/steps.d.ts.map +1 -1
  60. package/dist/tui.d.ts +1 -1
  61. package/dist/tui.d.ts.map +1 -1
  62. package/dist/types.d.ts +1 -1
  63. package/dist/types.d.ts.map +1 -1
  64. package/package.json +1 -1
  65. package/src/cli.ts +45 -4
  66. package/src/cmd/auth/index.ts +2 -1
  67. package/src/cmd/auth/whoami.ts +69 -0
  68. package/src/cmd/bundle/index.ts +2 -2
  69. package/src/cmd/cloud/deploy.ts +129 -0
  70. package/src/cmd/cloud/index.ts +8 -0
  71. package/src/cmd/dev/index.ts +5 -3
  72. package/src/cmd/env/delete.ts +62 -0
  73. package/src/cmd/env/get.ts +66 -0
  74. package/src/cmd/env/import.ts +117 -0
  75. package/src/cmd/env/index.ts +22 -0
  76. package/src/cmd/env/list.ts +69 -0
  77. package/src/cmd/env/pull.ts +93 -0
  78. package/src/cmd/env/push.ts +55 -0
  79. package/src/cmd/env/set.ts +86 -0
  80. package/src/cmd/project/download.ts +1 -1
  81. package/src/cmd/project/template-flow.ts +42 -2
  82. package/src/cmd/secret/delete.ts +55 -0
  83. package/src/cmd/secret/get.ts +67 -0
  84. package/src/cmd/secret/import.ts +79 -0
  85. package/src/cmd/secret/index.ts +22 -0
  86. package/src/cmd/secret/list.ts +69 -0
  87. package/src/cmd/secret/pull.ts +91 -0
  88. package/src/cmd/secret/push.ts +55 -0
  89. package/src/cmd/secret/set.ts +60 -0
  90. package/src/cmd/version/index.ts +2 -1
  91. package/src/config.ts +35 -5
  92. package/src/env-util.test.ts +194 -0
  93. package/src/env-util.ts +290 -0
  94. package/src/index.ts +5 -1
  95. package/src/schema-parser.ts +2 -3
  96. package/src/steps.ts +79 -4
  97. package/src/tui.ts +18 -9
  98. package/src/types.ts +1 -1
  99. package/dist/logger.d.ts +0 -24
  100. package/dist/logger.d.ts.map +0 -1
  101. package/src/logger.ts +0 -235
package/src/steps.ts CHANGED
@@ -7,6 +7,58 @@
7
7
 
8
8
  import type { ColorScheme } from './terminal';
9
9
 
10
+ /**
11
+ * Get the appropriate exit function (Bun.exit or process.exit)
12
+ */
13
+ function getExitFn(): (code: number) => never {
14
+ const bunExit = (globalThis as { Bun?: { exit?: (code: number) => never } }).Bun?.exit;
15
+ return typeof bunExit === 'function' ? bunExit : process.exit.bind(process);
16
+ }
17
+
18
+ /**
19
+ * Install interrupt handlers (SIGINT/SIGTERM + TTY raw mode for Ctrl+C)
20
+ */
21
+ function installInterruptHandlers(onInterrupt: () => void): () => void {
22
+ const cleanupFns: Array<() => void> = [];
23
+
24
+ const sigHandler = () => onInterrupt();
25
+ process.on('SIGINT', sigHandler);
26
+ process.on('SIGTERM', sigHandler);
27
+ cleanupFns.push(() => {
28
+ process.off('SIGINT', sigHandler);
29
+ process.off('SIGTERM', sigHandler);
30
+ });
31
+
32
+ // TTY raw mode fallback for Bun/Windows/inconsistent SIGINT delivery
33
+ const stdin = process.stdin as unknown as NodeJS.ReadStream;
34
+ if (stdin && stdin.isTTY) {
35
+ const onData = (buf: Buffer) => {
36
+ // Ctrl+C is ASCII ETX (0x03)
37
+ if (buf.length === 1 && buf[0] === 0x03) onInterrupt();
38
+ };
39
+ try {
40
+ stdin.setRawMode?.(true);
41
+ } catch {
42
+ // ignore if not supported
43
+ }
44
+ stdin.resume?.();
45
+ stdin.on('data', onData);
46
+ cleanupFns.push(() => {
47
+ stdin.off?.('data', onData);
48
+ stdin.pause?.();
49
+ try {
50
+ stdin.setRawMode?.(false);
51
+ } catch {
52
+ // ignore if setRawMode fails
53
+ }
54
+ });
55
+ }
56
+
57
+ return () => {
58
+ for (const fn of cleanupFns.splice(0)) fn();
59
+ };
60
+ }
61
+
10
62
  // Spinner frames
11
63
  const FRAMES = ['◐', '◓', '◑', '◒'];
12
64
 
@@ -35,7 +87,7 @@ const COLORS = {
35
87
  // Spinner color sequence
36
88
  const SPINNER_COLORS = ['cyan', 'blue', 'magenta', 'cyan'] as const;
37
89
 
38
- let currentColorScheme: ColorScheme = 'dark';
90
+ let currentColorScheme: ColorScheme = process.env.CI ? 'light' : 'dark';
39
91
 
40
92
  export function setStepsColorScheme(scheme: ColorScheme): void {
41
93
  currentColorScheme = scheme;
@@ -133,16 +185,33 @@ export async function runSteps(steps: Step[]): Promise<void> {
133
185
  // Hide cursor
134
186
  process.stdout.write('\x1B[?25l');
135
187
 
188
+ // Track active interval and interrupted state
189
+ let activeInterval: ReturnType<typeof setInterval> | null = null;
190
+ let interrupted = false;
191
+
192
+ // Set up Ctrl+C handler for graceful exit
193
+ const exit = getExitFn();
194
+ const onInterrupt = () => {
195
+ if (interrupted) return;
196
+ interrupted = true;
197
+ if (activeInterval) clearInterval(activeInterval);
198
+ process.stdout.write('\x1B[?25h\n'); // Show cursor
199
+ exit(130);
200
+ };
201
+ const restoreInterrupts = installInterruptHandlers(onInterrupt);
202
+
136
203
  try {
137
204
  // Initial render
138
205
  process.stdout.write(renderSteps(state, -1) + '\n');
139
206
 
140
207
  for (let stepIndex = 0; stepIndex < state.length; stepIndex++) {
208
+ if (interrupted) break;
209
+
141
210
  const step = state[stepIndex];
142
211
  let frameIndex = 0;
143
212
 
144
213
  // Start spinner animation
145
- const interval = setInterval(() => {
214
+ activeInterval = setInterval(() => {
146
215
  const colorKey = SPINNER_COLORS[frameIndex % SPINNER_COLORS.length];
147
216
  const color = getColor(colorKey);
148
217
  const frame = `${color}${COLORS.bold}${FRAMES[frameIndex % FRAMES.length]}${COLORS.reset}`;
@@ -175,7 +244,10 @@ export async function runSteps(steps: Step[]): Promise<void> {
175
244
  };
176
245
  }
177
246
 
178
- clearInterval(interval);
247
+ if (activeInterval) {
248
+ clearInterval(activeInterval);
249
+ activeInterval = null;
250
+ }
179
251
 
180
252
  // Clear progress and final render with outcome
181
253
  step.progress = undefined;
@@ -192,11 +264,14 @@ export async function runSteps(steps: Step[]): Promise<void> {
192
264
  }
193
265
 
194
266
  // Show cursor again
195
- process.stdout.write('\x1B[?25h\n');
267
+ process.stdout.write('\x1B[?25h');
196
268
  } catch (err) {
197
269
  // Ensure cursor is shown even if something goes wrong
198
270
  process.stdout.write('\x1B[?25h');
199
271
  throw err;
272
+ } finally {
273
+ // Remove signal/TTY handlers
274
+ restoreInterrupts();
200
275
  }
201
276
  }
202
277
 
package/src/tui.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  import enquirer from 'enquirer';
8
8
  import type { OrganizationList } from '@agentuity/server';
9
9
  import type { ColorScheme } from './terminal';
10
+ import { stringWidth } from 'bun';
10
11
 
11
12
  // Icons
12
13
  const ICONS = {
@@ -71,7 +72,7 @@ function getColors() {
71
72
  } as const;
72
73
  }
73
74
 
74
- let currentColorScheme: ColorScheme = 'dark';
75
+ let currentColorScheme: ColorScheme = process.env.CI ? 'light' : 'dark';
75
76
 
76
77
  export function setColorScheme(scheme: ColorScheme): void {
77
78
  currentColorScheme = scheme;
@@ -153,13 +154,13 @@ export function bold(text: string): string {
153
154
  /**
154
155
  * Format text as a link (blue and underlined)
155
156
  */
156
- export function link(url: string): string {
157
+ export function link(url: string, title?: string): string {
157
158
  const color = getColor('link');
158
159
  const reset = getColor('reset');
159
160
 
160
161
  // Check if terminal supports hyperlinks (OSC 8)
161
162
  if (supportsHyperlinks()) {
162
- return `\x1b]8;;${url}\x07${color}${url}${reset}\x1b]8;;\x07`;
163
+ return `\x1b]8;;${url}\x07${color}${title ?? url}${reset}\x1b]8;;\x07`;
163
164
  }
164
165
 
165
166
  return `${color}${url}${reset}`;
@@ -472,24 +473,32 @@ export function showSignupBenefits(): void {
472
473
  * Display a message when unauthenticated to let the user know certain capabilities are disabled
473
474
  */
474
475
  export function showLoggedOutMessage(): void {
475
- const CYAN = Bun.color('yellow', 'ansi-16m');
476
+ const YELLOW = Bun.color('yellow', 'ansi-16m');
476
477
  const TEXT =
477
478
  currentColorScheme === 'dark' ? Bun.color('white', 'ansi') : Bun.color('black', 'ansi');
478
479
  const RESET = '\x1b[0m';
479
480
 
481
+ const signupTitle = 'Sign up / Login';
482
+ const showInline = supportsHyperlinks();
483
+ const signupURL = 'https://app.agentuity.com/sign-up';
484
+ const signupLink = showInline
485
+ ? link(signupURL, signupTitle)
486
+ : ' '.repeat(stringWidth(signupTitle));
487
+ const showNewLine = showInline ? '' : `║ ${RESET}${link(signupURL)}${YELLOW} ║`;
488
+
480
489
  const lines = [
481
490
  '╔══════════════════════════════════════════════╗',
482
491
  `║ ⨺ Unauthenticated (local mode) ║`,
483
492
  '║ ║',
484
- `║ ${TEXT}Certain capabilities such as the AI services${CYAN} ║`,
485
- `║ ${TEXT}and devmode remote are unavailable when${CYAN} ║`,
486
- `║ ${TEXT}unauthenticated.${CYAN} ║`,
493
+ `║ ${TEXT}Certain capabilities such as the AI services${YELLOW} ║`,
494
+ `║ ${TEXT}and devmode remote are unavailable when${YELLOW} ║`,
495
+ `║ ${TEXT}unauthenticated.${YELLOW} ${signupLink}${YELLOW} ║`,
496
+ showNewLine,
487
497
  '╚══════════════════════════════════════════════╝',
488
498
  ];
489
499
 
490
500
  console.log('');
491
- lines.forEach((line) => console.log(CYAN + line + RESET));
492
- console.log('');
501
+ lines.filter(Boolean).forEach((line) => console.log(YELLOW + line + RESET));
493
502
  }
494
503
 
495
504
  /**
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Logger } from './logger';
1
+ import type { Logger } from '@agentuity/core';
2
2
  import type * as z from 'zod';
3
3
  import { z as zod } from 'zod';
4
4
 
package/dist/logger.d.ts DELETED
@@ -1,24 +0,0 @@
1
- import type { LogLevel } from './types';
2
- import type { ColorScheme } from './terminal';
3
- export declare class Logger {
4
- level: LogLevel;
5
- private showTimestamp;
6
- private colorScheme;
7
- private colors;
8
- private showPrefix;
9
- constructor(level?: LogLevel, showTimestamp?: boolean, colorScheme?: ColorScheme);
10
- setLevel(level: LogLevel): void;
11
- setTimestamp(enabled: boolean): void;
12
- setColorScheme(scheme: ColorScheme): void;
13
- setShowPrefix(show: boolean): void;
14
- private shouldLog;
15
- private log;
16
- debug(message: string, ...args: unknown[]): void;
17
- trace(message: string, ...args: unknown[]): void;
18
- info(message: string, ...args: unknown[]): void;
19
- warn(message: string, ...args: unknown[]): void;
20
- error(message: string, ...args: unknown[]): void;
21
- fatal(message: string, ...args: unknown[]): never;
22
- }
23
- export declare const logger: Logger;
24
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA8G9C,qBAAa,MAAM;IACX,KAAK,EAAE,QAAQ,CAAC;IACvB,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,UAAU,CAAQ;gBAGzB,KAAK,GAAE,QAAiB,EACxB,aAAa,GAAE,OAAe,EAC9B,WAAW,GAAE,WAAoB;IAQlC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpC,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAKzC,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAIlC,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,GAAG;IA0DX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK;CAIjD;AAED,eAAO,MAAM,MAAM,QAAqB,CAAC"}
package/src/logger.ts DELETED
@@ -1,235 +0,0 @@
1
- import type { LogLevel } from './types';
2
- import type { ColorScheme } from './terminal';
3
-
4
- const LOG_LEVELS: Record<LogLevel, number> = {
5
- debug: 0,
6
- trace: 1,
7
- info: 2,
8
- warn: 3,
9
- error: 4,
10
- };
11
-
12
- const BOLD = '\x1b[1m';
13
- const RESET = '\x1b[0m';
14
-
15
- // Helper to convert hex color to ANSI 24-bit color code
16
- function hexToAnsi(hex: string): string {
17
- const r = parseInt(hex.slice(1, 3), 16);
18
- const g = parseInt(hex.slice(3, 5), 16);
19
- const b = parseInt(hex.slice(5, 7), 16);
20
- return `\x1b[38;2;${r};${g};${b}m`;
21
- }
22
-
23
- function shouldUseColors(): boolean {
24
- // Check for NO_COLOR environment variable (any non-empty value disables colors)
25
- if (process.env.NO_COLOR) {
26
- return false;
27
- }
28
-
29
- // Check for TERM=dumb
30
- if (process.env.TERM === 'dumb') {
31
- return false;
32
- }
33
-
34
- // Check if stdout is a TTY
35
- if (!process.stdout.isTTY) {
36
- return false;
37
- }
38
-
39
- return true;
40
- }
41
-
42
- const USE_COLORS = shouldUseColors();
43
-
44
- interface LogColors {
45
- level: string;
46
- message: string;
47
- timestamp: string;
48
- }
49
-
50
- function getLogColors(scheme: ColorScheme): Record<LogLevel, LogColors> {
51
- if (scheme === 'light') {
52
- // Darker, high-contrast colors for light backgrounds
53
- return {
54
- trace: {
55
- level: hexToAnsi('#008B8B') + BOLD, // Dark cyan
56
- message: hexToAnsi('#4B4B4B'), // Dark gray
57
- timestamp: hexToAnsi('#808080'), // Gray
58
- },
59
- debug: {
60
- level: hexToAnsi('#0000CD') + BOLD, // Medium blue
61
- message: hexToAnsi('#006400'), // Dark green
62
- timestamp: hexToAnsi('#808080'),
63
- },
64
- info: {
65
- level: hexToAnsi('#FF8C00') + BOLD, // Dark orange
66
- message: hexToAnsi('#0066CC') + BOLD, // Strong blue
67
- timestamp: hexToAnsi('#808080'),
68
- },
69
- warn: {
70
- level: hexToAnsi('#9400D3') + BOLD, // Dark violet
71
- message: hexToAnsi('#8B008B'), // Dark magenta
72
- timestamp: hexToAnsi('#808080'),
73
- },
74
- error: {
75
- level: hexToAnsi('#DC143C') + BOLD, // Crimson
76
- message: hexToAnsi('#8B0000') + BOLD, // Dark red
77
- timestamp: hexToAnsi('#808080'),
78
- },
79
- };
80
- }
81
-
82
- // Dark mode colors (brighter for dark backgrounds)
83
- return {
84
- trace: {
85
- level: (Bun.color('cyan', 'ansi') ?? '') + BOLD,
86
- message: Bun.color('gray', 'ansi') ?? '',
87
- timestamp: hexToAnsi('#666666'),
88
- },
89
- debug: {
90
- level: (Bun.color('blue', 'ansi') ?? '') + BOLD,
91
- message: Bun.color('green', 'ansi') ?? '',
92
- timestamp: hexToAnsi('#666666'),
93
- },
94
- info: {
95
- level: (Bun.color('yellow', 'ansi') ?? '') + BOLD,
96
- message: (Bun.color('white', 'ansi') ?? '') + BOLD,
97
- timestamp: hexToAnsi('#666666'),
98
- },
99
- warn: {
100
- level: (Bun.color('magenta', 'ansi') ?? '') + BOLD,
101
- message: Bun.color('magenta', 'ansi') ?? '',
102
- timestamp: hexToAnsi('#666666'),
103
- },
104
- error: {
105
- level: (Bun.color('red', 'ansi') ?? '') + BOLD,
106
- message: Bun.color('red', 'ansi') ?? '',
107
- timestamp: hexToAnsi('#666666'),
108
- },
109
- };
110
- }
111
-
112
- export class Logger {
113
- public level: LogLevel;
114
- private showTimestamp: boolean;
115
- private colorScheme: ColorScheme;
116
- private colors: Record<LogLevel, LogColors>;
117
- private showPrefix = true;
118
-
119
- constructor(
120
- level: LogLevel = 'info',
121
- showTimestamp: boolean = false,
122
- colorScheme: ColorScheme = 'dark'
123
- ) {
124
- this.level = level;
125
- this.showTimestamp = showTimestamp;
126
- this.colorScheme = colorScheme;
127
- this.colors = getLogColors(this.colorScheme);
128
- }
129
-
130
- setLevel(level: LogLevel): void {
131
- this.level = level;
132
- }
133
-
134
- setTimestamp(enabled: boolean): void {
135
- this.showTimestamp = enabled;
136
- }
137
-
138
- setColorScheme(scheme: ColorScheme): void {
139
- this.colorScheme = scheme;
140
- this.colors = getLogColors(this.colorScheme);
141
- }
142
-
143
- setShowPrefix(show: boolean): void {
144
- this.showPrefix = show;
145
- }
146
-
147
- private shouldLog(level: LogLevel): boolean {
148
- return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
149
- }
150
-
151
- private log(level: LogLevel, message: string, ...args: unknown[]): void {
152
- if (!this.shouldLog(level) || !message) {
153
- return;
154
- }
155
-
156
- const colors = this.colors[level];
157
- const levelText = `[${level.toUpperCase()}]`;
158
-
159
- let output = '';
160
-
161
- if (USE_COLORS) {
162
- if (this.showPrefix) {
163
- if (this.showTimestamp) {
164
- const timestamp = new Date().toISOString();
165
- output = `${colors.timestamp}[${timestamp}]${RESET} ${colors.level}${levelText}${RESET} ${colors.message}${message}${RESET}`;
166
- } else {
167
- output = `${colors.level}${levelText}${RESET} ${colors.message}${message}${RESET}`;
168
- }
169
- } else {
170
- // No prefix - just the message with color
171
- output = `${colors.message}${message}${RESET}`;
172
- }
173
- } else {
174
- // No colors - plain text output
175
- if (this.showPrefix) {
176
- if (this.showTimestamp) {
177
- const timestamp = new Date().toISOString();
178
- output = `[${timestamp}] ${levelText} ${message}`;
179
- } else {
180
- output = `${levelText} ${message}`;
181
- }
182
- } else {
183
- // No prefix, no colors - just message
184
- output = message;
185
- }
186
- }
187
-
188
- if (level === 'error') {
189
- if (args.length > 0) {
190
- console.error(output, ...args);
191
- } else {
192
- console.error(output);
193
- }
194
- } else if (level === 'warn') {
195
- if (args.length > 0) {
196
- console.warn(output, ...args);
197
- } else {
198
- console.warn(output);
199
- }
200
- } else {
201
- if (args.length > 0) {
202
- console.log(output, ...args);
203
- } else {
204
- console.log(output);
205
- }
206
- }
207
- }
208
-
209
- debug(message: string, ...args: unknown[]): void {
210
- this.log('debug', message, ...args);
211
- }
212
-
213
- trace(message: string, ...args: unknown[]): void {
214
- this.log('trace', message, ...args);
215
- }
216
-
217
- info(message: string, ...args: unknown[]): void {
218
- this.log('info', message, ...args);
219
- }
220
-
221
- warn(message: string, ...args: unknown[]): void {
222
- this.log('warn', message, ...args);
223
- }
224
-
225
- error(message: string, ...args: unknown[]): void {
226
- this.log('error', message, ...args);
227
- }
228
-
229
- fatal(message: string, ...args: unknown[]): never {
230
- this.log('error', message, ...args);
231
- process.exit(1);
232
- }
233
- }
234
-
235
- export const logger = new Logger('info');