@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.
- package/bin/cli.ts +7 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cmd/auth/index.d.ts.map +1 -1
- package/dist/cmd/auth/whoami.d.ts +2 -0
- package/dist/cmd/auth/whoami.d.ts.map +1 -0
- package/dist/cmd/bundle/index.d.ts +1 -1
- package/dist/cmd/bundle/index.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts +2 -0
- package/dist/cmd/cloud/deploy.d.ts.map +1 -0
- package/dist/cmd/cloud/index.d.ts +2 -0
- package/dist/cmd/cloud/index.d.ts.map +1 -0
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/env/delete.d.ts +2 -0
- package/dist/cmd/env/delete.d.ts.map +1 -0
- package/dist/cmd/env/get.d.ts +2 -0
- package/dist/cmd/env/get.d.ts.map +1 -0
- package/dist/cmd/env/import.d.ts +2 -0
- package/dist/cmd/env/import.d.ts.map +1 -0
- package/dist/cmd/env/index.d.ts +2 -0
- package/dist/cmd/env/index.d.ts.map +1 -0
- package/dist/cmd/env/list.d.ts +2 -0
- package/dist/cmd/env/list.d.ts.map +1 -0
- package/dist/cmd/env/pull.d.ts +2 -0
- package/dist/cmd/env/pull.d.ts.map +1 -0
- package/dist/cmd/env/push.d.ts +2 -0
- package/dist/cmd/env/push.d.ts.map +1 -0
- package/dist/cmd/env/set.d.ts +2 -0
- package/dist/cmd/env/set.d.ts.map +1 -0
- package/dist/cmd/project/download.d.ts +1 -1
- package/dist/cmd/project/download.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.d.ts +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/secret/delete.d.ts +2 -0
- package/dist/cmd/secret/delete.d.ts.map +1 -0
- package/dist/cmd/secret/get.d.ts +2 -0
- package/dist/cmd/secret/get.d.ts.map +1 -0
- package/dist/cmd/secret/import.d.ts +2 -0
- package/dist/cmd/secret/import.d.ts.map +1 -0
- package/dist/cmd/secret/index.d.ts +2 -0
- package/dist/cmd/secret/index.d.ts.map +1 -0
- package/dist/cmd/secret/list.d.ts +2 -0
- package/dist/cmd/secret/list.d.ts.map +1 -0
- package/dist/cmd/secret/pull.d.ts +2 -0
- package/dist/cmd/secret/pull.d.ts.map +1 -0
- package/dist/cmd/secret/push.d.ts +2 -0
- package/dist/cmd/secret/push.d.ts.map +1 -0
- package/dist/cmd/secret/set.d.ts +2 -0
- package/dist/cmd/secret/set.d.ts.map +1 -0
- package/dist/cmd/version/index.d.ts.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/env-util.d.ts +67 -0
- package/dist/env-util.d.ts.map +1 -0
- package/dist/env-util.test.d.ts +2 -0
- package/dist/env-util.test.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/schema-parser.d.ts.map +1 -1
- package/dist/steps.d.ts.map +1 -1
- package/dist/tui.d.ts +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +45 -4
- package/src/cmd/auth/index.ts +2 -1
- package/src/cmd/auth/whoami.ts +69 -0
- package/src/cmd/bundle/index.ts +2 -2
- package/src/cmd/cloud/deploy.ts +129 -0
- package/src/cmd/cloud/index.ts +8 -0
- package/src/cmd/dev/index.ts +5 -3
- package/src/cmd/env/delete.ts +62 -0
- package/src/cmd/env/get.ts +66 -0
- package/src/cmd/env/import.ts +117 -0
- package/src/cmd/env/index.ts +22 -0
- package/src/cmd/env/list.ts +69 -0
- package/src/cmd/env/pull.ts +93 -0
- package/src/cmd/env/push.ts +55 -0
- package/src/cmd/env/set.ts +86 -0
- package/src/cmd/project/download.ts +1 -1
- package/src/cmd/project/template-flow.ts +42 -2
- package/src/cmd/secret/delete.ts +55 -0
- package/src/cmd/secret/get.ts +67 -0
- package/src/cmd/secret/import.ts +79 -0
- package/src/cmd/secret/index.ts +22 -0
- package/src/cmd/secret/list.ts +69 -0
- package/src/cmd/secret/pull.ts +91 -0
- package/src/cmd/secret/push.ts +55 -0
- package/src/cmd/secret/set.ts +60 -0
- package/src/cmd/version/index.ts +2 -1
- package/src/config.ts +35 -5
- package/src/env-util.test.ts +194 -0
- package/src/env-util.ts +290 -0
- package/src/index.ts +5 -1
- package/src/schema-parser.ts +2 -3
- package/src/steps.ts +79 -4
- package/src/tui.ts +18 -9
- package/src/types.ts +1 -1
- package/dist/logger.d.ts +0 -24
- package/dist/logger.d.ts.map +0 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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${
|
|
485
|
-
`║ ${TEXT}and devmode remote are unavailable when${
|
|
486
|
-
`║ ${TEXT}unauthenticated.${
|
|
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(
|
|
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
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
|
package/dist/logger.d.ts.map
DELETED
|
@@ -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');
|