berget 2.2.7 → 2.2.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 (130) hide show
  1. package/.github/workflows/publish.yml +6 -6
  2. package/.github/workflows/test.yml +1 -1
  3. package/.prettierrc +5 -3
  4. package/dist/index.js +24 -25
  5. package/dist/package.json +7 -3
  6. package/dist/src/agents/app.js +8 -8
  7. package/dist/src/agents/backend.js +3 -3
  8. package/dist/src/agents/devops.js +8 -8
  9. package/dist/src/agents/frontend.js +3 -3
  10. package/dist/src/agents/fullstack.js +3 -3
  11. package/dist/src/agents/index.js +18 -18
  12. package/dist/src/agents/quality.js +8 -8
  13. package/dist/src/agents/security.js +8 -8
  14. package/dist/src/client.js +115 -127
  15. package/dist/src/commands/api-keys.js +181 -202
  16. package/dist/src/commands/auth.js +16 -25
  17. package/dist/src/commands/autocomplete.js +8 -8
  18. package/dist/src/commands/billing.js +10 -19
  19. package/dist/src/commands/chat.js +139 -170
  20. package/dist/src/commands/clusters.js +21 -30
  21. package/dist/src/commands/code/__tests__/auth-sync.test.js +189 -186
  22. package/dist/src/commands/code/__tests__/fake-api-key-service.js +3 -13
  23. package/dist/src/commands/code/__tests__/fake-auth-service.js +21 -29
  24. package/dist/src/commands/code/__tests__/fake-command-runner.js +22 -33
  25. package/dist/src/commands/code/__tests__/fake-file-store.js +19 -41
  26. package/dist/src/commands/code/__tests__/fake-prompter.js +81 -97
  27. package/dist/src/commands/code/__tests__/setup-flow.test.js +295 -295
  28. package/dist/src/commands/code/adapters/clack-prompter.js +15 -32
  29. package/dist/src/commands/code/adapters/fs-file-store.js +25 -44
  30. package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -41
  31. package/dist/src/commands/code/auth-sync.js +215 -228
  32. package/dist/src/commands/code/errors.js +15 -12
  33. package/dist/src/commands/code/setup.js +390 -425
  34. package/dist/src/commands/code.js +279 -294
  35. package/dist/src/commands/index.js +5 -5
  36. package/dist/src/commands/models.js +16 -25
  37. package/dist/src/commands/users.js +9 -18
  38. package/dist/src/constants/command-structure.js +138 -138
  39. package/dist/src/services/api-key-service.js +132 -152
  40. package/dist/src/services/auth-service.js +81 -95
  41. package/dist/src/services/browser-auth.js +121 -131
  42. package/dist/src/services/chat-service.js +369 -386
  43. package/dist/src/services/cluster-service.js +47 -62
  44. package/dist/src/services/collaborator-service.js +9 -21
  45. package/dist/src/services/flux-service.js +13 -25
  46. package/dist/src/services/helm-service.js +9 -21
  47. package/dist/src/services/kubectl-service.js +15 -29
  48. package/dist/src/utils/config-checker.js +8 -8
  49. package/dist/src/utils/config-loader.js +109 -109
  50. package/dist/src/utils/default-api-key.js +129 -139
  51. package/dist/src/utils/env-manager.js +55 -66
  52. package/dist/src/utils/error-handler.js +62 -62
  53. package/dist/src/utils/logger.js +74 -67
  54. package/dist/src/utils/markdown-renderer.js +28 -28
  55. package/dist/src/utils/opencode-validator.js +67 -69
  56. package/dist/src/utils/token-manager.js +67 -65
  57. package/dist/tests/commands/chat.test.js +30 -39
  58. package/dist/tests/commands/code.test.js +186 -195
  59. package/dist/tests/utils/config-loader.test.js +107 -107
  60. package/dist/tests/utils/env-manager.test.js +81 -90
  61. package/dist/tests/utils/opencode-validator.test.js +42 -41
  62. package/dist/vitest.config.js +1 -1
  63. package/eslint.config.mjs +65 -30
  64. package/index.ts +30 -31
  65. package/package.json +7 -3
  66. package/src/agents/app.ts +9 -9
  67. package/src/agents/backend.ts +4 -4
  68. package/src/agents/devops.ts +9 -9
  69. package/src/agents/frontend.ts +4 -4
  70. package/src/agents/fullstack.ts +4 -4
  71. package/src/agents/index.ts +27 -25
  72. package/src/agents/quality.ts +9 -9
  73. package/src/agents/security.ts +9 -9
  74. package/src/agents/types.ts +10 -10
  75. package/src/client.ts +85 -77
  76. package/src/commands/api-keys.ts +180 -185
  77. package/src/commands/auth.ts +15 -14
  78. package/src/commands/autocomplete.ts +10 -10
  79. package/src/commands/billing.ts +13 -12
  80. package/src/commands/chat.ts +145 -142
  81. package/src/commands/clusters.ts +20 -19
  82. package/src/commands/code/__tests__/auth-sync.test.ts +176 -175
  83. package/src/commands/code/__tests__/fake-api-key-service.ts +2 -2
  84. package/src/commands/code/__tests__/fake-auth-service.ts +18 -18
  85. package/src/commands/code/__tests__/fake-command-runner.ts +28 -22
  86. package/src/commands/code/__tests__/fake-file-store.ts +15 -15
  87. package/src/commands/code/__tests__/fake-prompter.ts +86 -85
  88. package/src/commands/code/__tests__/setup-flow.test.ts +253 -251
  89. package/src/commands/code/adapters/clack-prompter.ts +32 -30
  90. package/src/commands/code/adapters/fs-file-store.ts +18 -17
  91. package/src/commands/code/adapters/spawn-command-runner.ts +20 -15
  92. package/src/commands/code/auth-sync.ts +210 -210
  93. package/src/commands/code/errors.ts +11 -11
  94. package/src/commands/code/ports/auth-services.ts +7 -7
  95. package/src/commands/code/ports/command-runner.ts +2 -2
  96. package/src/commands/code/ports/file-store.ts +3 -3
  97. package/src/commands/code/ports/prompter.ts +13 -13
  98. package/src/commands/code/setup.ts +408 -406
  99. package/src/commands/code.ts +288 -287
  100. package/src/commands/index.ts +11 -10
  101. package/src/commands/models.ts +19 -18
  102. package/src/commands/users.ts +11 -10
  103. package/src/constants/command-structure.ts +159 -159
  104. package/src/services/api-key-service.ts +85 -85
  105. package/src/services/auth-service.ts +55 -54
  106. package/src/services/browser-auth.ts +62 -62
  107. package/src/services/chat-service.ts +170 -171
  108. package/src/services/cluster-service.ts +28 -28
  109. package/src/services/collaborator-service.ts +6 -6
  110. package/src/services/flux-service.ts +17 -17
  111. package/src/services/helm-service.ts +11 -11
  112. package/src/services/kubectl-service.ts +12 -12
  113. package/src/types/api.d.ts +1933 -1933
  114. package/src/types/json.d.ts +1 -1
  115. package/src/utils/config-checker.ts +7 -7
  116. package/src/utils/config-loader.ts +130 -129
  117. package/src/utils/default-api-key.ts +81 -80
  118. package/src/utils/env-manager.ts +37 -37
  119. package/src/utils/error-handler.ts +64 -64
  120. package/src/utils/logger.ts +72 -66
  121. package/src/utils/markdown-renderer.ts +28 -28
  122. package/src/utils/opencode-validator.ts +72 -71
  123. package/src/utils/token-manager.ts +69 -68
  124. package/tests/commands/chat.test.ts +32 -31
  125. package/tests/commands/code.test.ts +182 -181
  126. package/tests/utils/config-loader.test.ts +111 -110
  127. package/tests/utils/env-manager.test.ts +83 -79
  128. package/tests/utils/opencode-validator.test.ts +43 -42
  129. package/tsconfig.json +2 -1
  130. package/vitest.config.ts +2 -2
@@ -1,15 +1,35 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { writeFile } from "fs/promises";
4
- import chalk from "chalk";
5
- import dotenv from "dotenv";
1
+ import chalk from 'chalk';
2
+ import dotenv from 'dotenv';
3
+ import fs from 'node:fs';
4
+ import { writeFile } from 'node:fs/promises';
5
+ import path from 'node:path';
6
6
 
7
7
  export interface EnvUpdateOptions {
8
+ comment?: string;
8
9
  envPath?: string;
10
+ force?: boolean;
9
11
  key: string;
10
12
  value: string;
11
- comment?: string;
12
- force?: boolean;
13
+ }
14
+
15
+ /**
16
+ * Checks if a .env file exists and contains a specific key
17
+ */
18
+ export function hasEnvKey(
19
+ environmentPath: string = path.join(process.cwd(), '.env'),
20
+ key: string,
21
+ ): boolean {
22
+ if (!fs.existsSync(environmentPath)) {
23
+ return false;
24
+ }
25
+
26
+ try {
27
+ const content = fs.readFileSync(environmentPath, 'utf8');
28
+ const parsed = dotenv.parse(content);
29
+ return key in parsed;
30
+ } catch {
31
+ return false;
32
+ }
13
33
  }
14
34
 
15
35
  /**
@@ -18,20 +38,20 @@ export interface EnvUpdateOptions {
18
38
  */
19
39
  export async function updateEnvFile(options: EnvUpdateOptions): Promise<boolean> {
20
40
  const {
21
- envPath = path.join(process.cwd(), ".env"),
22
- key,
23
- value,
24
41
  comment,
42
+ envPath: environmentPath = path.join(process.cwd(), '.env'),
25
43
  force = false,
44
+ key,
45
+ value,
26
46
  } = options;
27
47
 
28
48
  try {
29
- let existingContent = "";
49
+ let existingContent = '';
30
50
  let parsed: Record<string, string> = {};
31
51
 
32
52
  // Read existing .env file if it exists
33
- if (fs.existsSync(envPath)) {
34
- existingContent = fs.readFileSync(envPath, "utf8");
53
+ if (fs.existsSync(environmentPath)) {
54
+ existingContent = fs.readFileSync(environmentPath, 'utf8');
35
55
  parsed = dotenv.parse(existingContent);
36
56
  }
37
57
 
@@ -45,7 +65,7 @@ export async function updateEnvFile(options: EnvUpdateOptions): Promise<boolean>
45
65
  parsed[key] = value;
46
66
 
47
67
  // Generate new .env content
48
- let newContent = "";
68
+ let newContent = '';
49
69
 
50
70
  // Add comment at the top if this is a new file
51
71
  if (!existingContent && comment) {
@@ -53,12 +73,12 @@ export async function updateEnvFile(options: EnvUpdateOptions): Promise<boolean>
53
73
  }
54
74
 
55
75
  // Convert parsed object back to .env format
56
- for (const [envKey, envValue] of Object.entries(parsed)) {
57
- newContent += `${envKey}=${envValue}\n`;
76
+ for (const [environmentKey, environmentValue] of Object.entries(parsed)) {
77
+ newContent += `${environmentKey}=${environmentValue}\n`;
58
78
  }
59
79
 
60
80
  // Write the updated content
61
- await writeFile(envPath, newContent.trim() + "\n");
81
+ await writeFile(environmentPath, newContent.trim() + '\n');
62
82
 
63
83
  if (existingContent) {
64
84
  console.log(chalk.green(`✓ Updated .env with ${key}`));
@@ -72,23 +92,3 @@ export async function updateEnvFile(options: EnvUpdateOptions): Promise<boolean>
72
92
  throw error;
73
93
  }
74
94
  }
75
-
76
- /**
77
- * Checks if a .env file exists and contains a specific key
78
- */
79
- export function hasEnvKey(
80
- envPath: string = path.join(process.cwd(), ".env"),
81
- key: string
82
- ): boolean {
83
- if (!fs.existsSync(envPath)) {
84
- return false;
85
- }
86
-
87
- try {
88
- const content = fs.readFileSync(envPath, "utf8");
89
- const parsed = dotenv.parse(content);
90
- return key in parsed;
91
- } catch {
92
- return false;
93
- }
94
- }
@@ -1,4 +1,4 @@
1
- import chalk from "chalk";
1
+ import chalk from 'chalk';
2
2
 
3
3
  /**
4
4
  * Formats and prints error messages in a consistent way
@@ -6,19 +6,19 @@ import chalk from "chalk";
6
6
  export function handleError(message: string, error: any): void {
7
7
  console.error(chalk.red(`❌ Error: ${message}`));
8
8
 
9
- let errorDetails = "";
10
- let errorCode = "";
11
- let errorType = "";
9
+ let errorDetails = '';
10
+ let errorCode = '';
11
+ let errorType = '';
12
12
 
13
13
  // If the error is a string (like JSON.stringify(error))
14
- if (typeof error === "string") {
14
+ if (typeof error === 'string') {
15
15
  try {
16
16
  // Try to parse it as JSON
17
17
  const parsedError = JSON.parse(error);
18
18
  if (parsedError.error) {
19
19
  errorDetails = parsedError.error.message || parsedError.error;
20
20
  errorCode = parsedError.error.code || parsedError.code;
21
- errorType = parsedError.error.type || "";
21
+ errorType = parsedError.error.type || '';
22
22
  } else {
23
23
  errorDetails = error;
24
24
  }
@@ -51,101 +51,101 @@ export function handleError(message: string, error: any): void {
51
51
  function provideTroubleshootingTips(
52
52
  errorType: string,
53
53
  errorCode: string,
54
- errorDetails: string
54
+ errorDetails: string,
55
55
  ): void {
56
- console.error(chalk.blue("\n💡 Troubleshooting tips:"));
56
+ console.error(chalk.blue('\n💡 Troubleshooting tips:'));
57
57
 
58
58
  // Authentication errors
59
59
  if (
60
- errorType === "authentication_error" ||
61
- errorCode === "AUTH_FAILED" ||
62
- errorDetails?.includes("Unauthorized") ||
63
- errorDetails?.includes("Authentication failed")
60
+ errorType === 'authentication_error' ||
61
+ errorCode === 'AUTH_FAILED' ||
62
+ errorDetails?.includes('Unauthorized') ||
63
+ errorDetails?.includes('Authentication failed')
64
64
  ) {
65
- console.error(chalk.yellow(" 🔐 Authentication issue detected:"));
66
- console.error(chalk.white(" • Run `berget auth login` to log in"));
67
- console.error(chalk.white(" • Check if your session has expired"));
68
- console.error(chalk.white(" • Verify you have the correct permissions"));
65
+ console.error(chalk.yellow(' 🔐 Authentication issue detected:'));
66
+ console.error(chalk.white(' • Run `berget auth login` to log in'));
67
+ console.error(chalk.white(' • Check if your session has expired'));
68
+ console.error(chalk.white(' • Verify you have the correct permissions'));
69
69
  }
70
70
 
71
71
  // Network/connection errors
72
72
  if (
73
- errorDetails?.includes("fetch failed") ||
74
- errorDetails?.includes("ECONNREFUSED") ||
75
- errorDetails?.includes("ENOTFOUND") ||
76
- errorDetails?.includes("network")
73
+ errorDetails?.includes('fetch failed') ||
74
+ errorDetails?.includes('ECONNREFUSED') ||
75
+ errorDetails?.includes('ENOTFOUND') ||
76
+ errorDetails?.includes('network')
77
77
  ) {
78
- console.error(chalk.yellow(" 🌐 Network issue detected:"));
79
- console.error(chalk.white(" • Check your internet connection"));
80
- console.error(chalk.white(" • Verify you can reach api.berget.ai"));
81
- console.error(chalk.white(" • Try again in a few minutes"));
82
- console.error(chalk.white(" • Check if any firewall is blocking the request"));
78
+ console.error(chalk.yellow(' 🌐 Network issue detected:'));
79
+ console.error(chalk.white(' • Check your internet connection'));
80
+ console.error(chalk.white(' • Verify you can reach api.berget.ai'));
81
+ console.error(chalk.white(' • Try again in a few minutes'));
82
+ console.error(chalk.white(' • Check if any firewall is blocking the request'));
83
83
  }
84
84
 
85
85
  // API key errors
86
86
  if (
87
- errorCode?.includes("API_KEY") ||
88
- errorDetails?.includes("API key") ||
89
- errorType === "invalid_request_error"
87
+ errorCode?.includes('API_KEY') ||
88
+ errorDetails?.includes('API key') ||
89
+ errorType === 'invalid_request_error'
90
90
  ) {
91
- console.error(chalk.yellow(" 🔑 API key issue detected:"));
92
- console.error(chalk.white(" • Run `berget api-keys list` to check your keys"));
91
+ console.error(chalk.yellow(' 🔑 API key issue detected:'));
92
+ console.error(chalk.white(' • Run `berget api-keys list` to check your keys'));
93
93
  console.error(
94
- chalk.white(' • Create a new key with `berget api-keys create --name "My Key"`')
94
+ chalk.white(' • Create a new key with `berget api-keys create --name "My Key"`'),
95
95
  );
96
- console.error(chalk.white(" • Set a default key with `berget api-keys set-default <id>`"));
97
- console.error(chalk.white(" • Check if your API key has expired"));
96
+ console.error(chalk.white(' • Set a default key with `berget api-keys set-default <id>`'));
97
+ console.error(chalk.white(' • Check if your API key has expired'));
98
98
  }
99
99
 
100
100
  // Rate limiting
101
101
  if (
102
- errorCode === "RATE_LIMIT_EXCEEDED" ||
103
- errorDetails?.includes("rate limit") ||
104
- errorDetails?.includes("too many requests")
102
+ errorCode === 'RATE_LIMIT_EXCEEDED' ||
103
+ errorDetails?.includes('rate limit') ||
104
+ errorDetails?.includes('too many requests')
105
105
  ) {
106
- console.error(chalk.yellow(" ⏱️ Rate limit exceeded:"));
107
- console.error(chalk.white(" • Wait a few minutes before trying again"));
108
- console.error(chalk.white(" • Consider upgrading your plan for higher limits"));
109
- console.error(chalk.white(" • Use `berget billing get-usage` to check your usage"));
106
+ console.error(chalk.yellow(' ⏱️ Rate limit exceeded:'));
107
+ console.error(chalk.white(' • Wait a few minutes before trying again'));
108
+ console.error(chalk.white(' • Consider upgrading your plan for higher limits'));
109
+ console.error(chalk.white(' • Use `berget billing get-usage` to check your usage'));
110
110
  }
111
111
 
112
112
  // Server errors
113
113
  if (
114
- errorCode?.includes("SERVER_ERROR") ||
115
- errorType === "server_error" ||
116
- (errorCode && parseInt(errorCode) >= 500)
114
+ errorCode?.includes('SERVER_ERROR') ||
115
+ errorType === 'server_error' ||
116
+ (errorCode && Number.parseInt(errorCode) >= 500)
117
117
  ) {
118
- console.error(chalk.yellow(" 🖥️ Server issue detected:"));
119
- console.error(chalk.white(" • This is a temporary problem on our end"));
120
- console.error(chalk.white(" • Try again in a few minutes"));
121
- console.error(chalk.white(" • Check status.berget.ai for service status"));
122
- console.error(chalk.white(" • Contact support if the problem persists"));
118
+ console.error(chalk.yellow(' 🖥️ Server issue detected:'));
119
+ console.error(chalk.white(' • This is a temporary problem on our end'));
120
+ console.error(chalk.white(' • Try again in a few minutes'));
121
+ console.error(chalk.white(' • Check status.berget.ai for service status'));
122
+ console.error(chalk.white(' • Contact support if the problem persists'));
123
123
  }
124
124
 
125
125
  // Cluster errors
126
- if (errorCode?.includes("CLUSTERS") || errorDetails?.includes("cluster")) {
127
- console.error(chalk.yellow(" 🏗️ Cluster issue detected:"));
128
- console.error(chalk.white(" • Clusters may be temporarily unavailable"));
129
- console.error(chalk.white(" • Try again later or contact support"));
130
- console.error(chalk.white(" • Check your cluster permissions"));
126
+ if (errorCode?.includes('CLUSTERS') || errorDetails?.includes('cluster')) {
127
+ console.error(chalk.yellow(' 🏗️ Cluster issue detected:'));
128
+ console.error(chalk.white(' • Clusters may be temporarily unavailable'));
129
+ console.error(chalk.white(' • Try again later or contact support'));
130
+ console.error(chalk.white(' • Check your cluster permissions'));
131
131
  }
132
132
 
133
133
  // Generic fallback
134
134
  if (
135
- !errorType?.includes("authentication") &&
136
- !errorDetails?.includes("fetch failed") &&
137
- !errorCode?.includes("API_KEY") &&
138
- !errorCode?.includes("RATE_LIMIT") &&
139
- !errorCode?.includes("SERVER_ERROR") &&
140
- !errorCode?.includes("CLUSTERS")
135
+ !errorType?.includes('authentication') &&
136
+ !errorDetails?.includes('fetch failed') &&
137
+ !errorCode?.includes('API_KEY') &&
138
+ !errorCode?.includes('RATE_LIMIT') &&
139
+ !errorCode?.includes('SERVER_ERROR') &&
140
+ !errorCode?.includes('CLUSTERS')
141
141
  ) {
142
- console.error(chalk.yellow(" ❓ General issue:"));
143
- console.error(chalk.white(" • Try running the command with --debug for more info"));
144
- console.error(chalk.white(" • Check your configuration with `berget auth whoami`"));
145
- console.error(chalk.white(" • Contact support if the problem persists"));
142
+ console.error(chalk.yellow(' ❓ General issue:'));
143
+ console.error(chalk.white(' • Try running the command with --debug for more info'));
144
+ console.error(chalk.white(' • Check your configuration with `berget auth whoami`'));
145
+ console.error(chalk.white(' • Contact support if the problem persists'));
146
146
  }
147
147
 
148
148
  console.error(
149
- chalk.dim("\nNeed more help? Visit https://docs.berget.ai or contact support@berget.ai")
149
+ chalk.dim('\nNeed more help? Visit https://docs.berget.ai or contact support@berget.ai'),
150
150
  );
151
151
  }
@@ -1,4 +1,4 @@
1
- import chalk from "chalk";
1
+ import chalk from 'chalk';
2
2
 
3
3
  /**
4
4
  * Log levels in order of increasing verbosity
@@ -22,9 +22,9 @@ export class Logger {
22
22
  // Set log level from environment variable or command line argument
23
23
  if (process.env.LOG_LEVEL) {
24
24
  this.setLogLevelFromString(process.env.LOG_LEVEL);
25
- } else if (process.argv.includes("--debug")) {
25
+ } else if (process.argv.includes('--debug')) {
26
26
  this.logLevel = LogLevel.DEBUG;
27
- } else if (process.argv.includes("--quiet")) {
27
+ } else if (process.argv.includes('--quiet')) {
28
28
  this.logLevel = LogLevel.ERROR;
29
29
  }
30
30
  }
@@ -37,36 +37,29 @@ export class Logger {
37
37
  }
38
38
 
39
39
  /**
40
- * Set the log level from a string
40
+ * Log a debug message (only shown at DEBUG level)
41
41
  */
42
- private setLogLevelFromString(level: string): void {
43
- switch (level.toLowerCase()) {
44
- case "none":
45
- this.logLevel = LogLevel.NONE;
46
- break;
47
- case "error":
48
- this.logLevel = LogLevel.ERROR;
49
- break;
50
- case "warn":
51
- this.logLevel = LogLevel.WARN;
52
- break;
53
- case "info":
54
- this.logLevel = LogLevel.INFO;
55
- break;
56
- case "debug":
57
- this.logLevel = LogLevel.DEBUG;
58
- break;
59
- default:
60
- // Invalid log level, keep default
61
- console.warn(`Invalid log level: ${level}. Using default (INFO).`);
42
+ public debug(message: string, ...arguments_: any[]): void {
43
+ if (this.logLevel >= LogLevel.DEBUG) {
44
+ if (arguments_.length > 0) {
45
+ console.log(chalk.yellow(`DEBUG: ${message}`), ...arguments_);
46
+ } else {
47
+ console.log(chalk.yellow(`DEBUG: ${message}`));
48
+ }
62
49
  }
63
50
  }
64
51
 
65
52
  /**
66
- * Set the log level
53
+ * Log an error message (shown at ERROR level and above)
67
54
  */
68
- public setLogLevel(level: LogLevel): void {
69
- this.logLevel = level;
55
+ public error(message: string, ...arguments_: any[]): void {
56
+ if (this.logLevel >= LogLevel.ERROR) {
57
+ if (arguments_.length > 0) {
58
+ console.error(chalk.red(message), ...arguments_);
59
+ } else {
60
+ console.error(chalk.red(message));
61
+ }
62
+ }
70
63
  }
71
64
 
72
65
  /**
@@ -77,79 +70,92 @@ export class Logger {
77
70
  }
78
71
 
79
72
  /**
80
- * Log a debug message (only shown at DEBUG level)
73
+ * Log an info message (shown at INFO level and above)
81
74
  */
82
- public debug(message: string, ...args: any[]): void {
83
- if (this.logLevel >= LogLevel.DEBUG) {
84
- if (args.length > 0) {
85
- console.log(chalk.yellow(`DEBUG: ${message}`), ...args);
75
+ public info(message: string, ...arguments_: any[]): void {
76
+ if (this.logLevel >= LogLevel.INFO) {
77
+ if (arguments_.length > 0) {
78
+ console.log(chalk.blue(message), ...arguments_);
86
79
  } else {
87
- console.log(chalk.yellow(`DEBUG: ${message}`));
80
+ console.log(chalk.blue(message));
88
81
  }
89
82
  }
90
83
  }
91
84
 
92
85
  /**
93
- * Log an info message (shown at INFO level and above)
86
+ * Log a plain message without color (shown at INFO level and above)
94
87
  */
95
- public info(message: string, ...args: any[]): void {
88
+ public log(message: string, ...arguments_: any[]): void {
96
89
  if (this.logLevel >= LogLevel.INFO) {
97
- if (args.length > 0) {
98
- console.log(chalk.blue(message), ...args);
90
+ if (arguments_.length > 0) {
91
+ console.log(message, ...arguments_);
99
92
  } else {
100
- console.log(chalk.blue(message));
93
+ console.log(message);
101
94
  }
102
95
  }
103
96
  }
104
97
 
105
98
  /**
106
- * Log a warning message (shown at WARN level and above)
99
+ * Set the log level
107
100
  */
108
- public warn(message: string, ...args: any[]): void {
109
- if (this.logLevel >= LogLevel.WARN) {
110
- if (args.length > 0) {
111
- console.log(chalk.yellow(message), ...args);
112
- } else {
113
- console.log(chalk.yellow(message));
114
- }
115
- }
101
+ public setLogLevel(level: LogLevel): void {
102
+ this.logLevel = level;
116
103
  }
117
104
 
118
105
  /**
119
- * Log an error message (shown at ERROR level and above)
106
+ * Log a success message (shown at INFO level and above)
120
107
  */
121
- public error(message: string, ...args: any[]): void {
122
- if (this.logLevel >= LogLevel.ERROR) {
123
- if (args.length > 0) {
124
- console.error(chalk.red(message), ...args);
108
+ public success(message: string, ...arguments_: any[]): void {
109
+ if (this.logLevel >= LogLevel.INFO) {
110
+ if (arguments_.length > 0) {
111
+ console.log(chalk.green(message), ...arguments_);
125
112
  } else {
126
- console.error(chalk.red(message));
113
+ console.log(chalk.green(message));
127
114
  }
128
115
  }
129
116
  }
130
117
 
131
118
  /**
132
- * Log a success message (shown at INFO level and above)
119
+ * Log a warning message (shown at WARN level and above)
133
120
  */
134
- public success(message: string, ...args: any[]): void {
135
- if (this.logLevel >= LogLevel.INFO) {
136
- if (args.length > 0) {
137
- console.log(chalk.green(message), ...args);
121
+ public warn(message: string, ...arguments_: any[]): void {
122
+ if (this.logLevel >= LogLevel.WARN) {
123
+ if (arguments_.length > 0) {
124
+ console.log(chalk.yellow(message), ...arguments_);
138
125
  } else {
139
- console.log(chalk.green(message));
126
+ console.log(chalk.yellow(message));
140
127
  }
141
128
  }
142
129
  }
143
130
 
144
131
  /**
145
- * Log a plain message without color (shown at INFO level and above)
132
+ * Set the log level from a string
146
133
  */
147
- public log(message: string, ...args: any[]): void {
148
- if (this.logLevel >= LogLevel.INFO) {
149
- if (args.length > 0) {
150
- console.log(message, ...args);
151
- } else {
152
- console.log(message);
134
+ private setLogLevelFromString(level: string): void {
135
+ switch (level.toLowerCase()) {
136
+ case 'debug': {
137
+ this.logLevel = LogLevel.DEBUG;
138
+ break;
139
+ }
140
+ case 'error': {
141
+ this.logLevel = LogLevel.ERROR;
142
+ break;
143
+ }
144
+ case 'info': {
145
+ this.logLevel = LogLevel.INFO;
146
+ break;
147
+ }
148
+ case 'none': {
149
+ this.logLevel = LogLevel.NONE;
150
+ break;
151
+ }
152
+ case 'warn': {
153
+ this.logLevel = LogLevel.WARN;
154
+ break;
155
+ }
156
+ default: {
157
+ // Invalid log level, keep default
158
+ console.warn(`Invalid log level: ${level}. Using default (INFO).`);
153
159
  }
154
160
  }
155
161
  }
@@ -1,45 +1,27 @@
1
- import { marked } from "marked";
2
- import TerminalRenderer from "marked-terminal";
3
- import chalk from "chalk";
1
+ import chalk from 'chalk';
2
+ import { marked } from 'marked';
3
+ import TerminalRenderer from 'marked-terminal';
4
4
 
5
5
  // Configure marked to use the terminal renderer
6
6
  marked.setOptions({
7
7
  renderer: new TerminalRenderer({
8
+ blockquote: chalk.gray.italic,
8
9
  // Customize the rendering options
9
10
  code: chalk.cyan,
10
- blockquote: chalk.gray.italic,
11
- table: chalk.white,
12
- listitem: chalk.yellow,
13
- strong: chalk.bold,
11
+ // Customize code block rendering
12
+ codespan: chalk.cyan,
14
13
  em: chalk.italic,
15
14
  heading: chalk.bold.blueBright,
16
15
  hr: chalk.gray,
17
16
  link: chalk.blue.underline,
17
+ listitem: chalk.yellow,
18
+ strong: chalk.bold,
19
+ table: chalk.white,
18
20
  // Adjust the width to fit the terminal
19
21
  width: process.stdout.columns || 80,
20
- // Customize code block rendering
21
- codespan: chalk.cyan,
22
22
  }),
23
23
  });
24
24
 
25
- /**
26
- * Render markdown text to terminal-friendly formatted text
27
- * @param markdown The markdown text to render
28
- * @returns Formatted text for terminal display
29
- */
30
- export function renderMarkdown(markdown: string): string {
31
- if (!markdown) return "";
32
-
33
- try {
34
- // Convert markdown to terminal-friendly text
35
- return marked(markdown);
36
- } catch (error) {
37
- // If rendering fails, return the original text
38
- console.error(`Error rendering markdown: ${error}`);
39
- return markdown;
40
- }
41
- }
42
-
43
25
  /**
44
26
  * Check if a string contains markdown formatting
45
27
  * @param text The text to check
@@ -64,5 +46,23 @@ export function containsMarkdown(text: string): boolean {
64
46
  /^===+$/m, // Alternative headers
65
47
  ];
66
48
 
67
- return markdownPatterns.some(pattern => pattern.test(text));
49
+ return markdownPatterns.some((pattern) => pattern.test(text));
50
+ }
51
+
52
+ /**
53
+ * Render markdown text to terminal-friendly formatted text
54
+ * @param markdown The markdown text to render
55
+ * @returns Formatted text for terminal display
56
+ */
57
+ export function renderMarkdown(markdown: string): string {
58
+ if (!markdown) return '';
59
+
60
+ try {
61
+ // Convert markdown to terminal-friendly text
62
+ return marked(markdown);
63
+ } catch (error) {
64
+ // If rendering fails, return the original text
65
+ console.error(`Error rendering markdown: ${error}`);
66
+ return markdown;
67
+ }
68
68
  }