berget 2.2.6 → 2.2.7

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 (144) hide show
  1. package/.github/workflows/publish.yml +6 -6
  2. package/.github/workflows/test.yml +11 -5
  3. package/.husky/pre-commit +1 -0
  4. package/.prettierignore +15 -0
  5. package/.prettierrc +5 -3
  6. package/CONTRIBUTING.md +38 -0
  7. package/README.md +2 -148
  8. package/dist/index.js +21 -21
  9. package/dist/package.json +28 -2
  10. package/dist/src/agents/app.js +28 -0
  11. package/dist/src/agents/backend.js +25 -0
  12. package/dist/src/agents/devops.js +34 -0
  13. package/dist/src/agents/frontend.js +25 -0
  14. package/dist/src/agents/fullstack.js +25 -0
  15. package/dist/src/agents/index.js +61 -0
  16. package/dist/src/agents/quality.js +70 -0
  17. package/dist/src/agents/security.js +26 -0
  18. package/dist/src/agents/types.js +2 -0
  19. package/dist/src/client.js +54 -62
  20. package/dist/src/commands/api-keys.js +132 -140
  21. package/dist/src/commands/auth.js +9 -9
  22. package/dist/src/commands/autocomplete.js +9 -9
  23. package/dist/src/commands/billing.js +7 -9
  24. package/dist/src/commands/chat.js +90 -92
  25. package/dist/src/commands/clusters.js +12 -12
  26. package/dist/src/commands/code/__tests__/auth-sync.test.js +348 -0
  27. package/dist/src/commands/code/__tests__/fake-api-key-service.js +23 -0
  28. package/dist/src/commands/code/__tests__/fake-auth-service.js +55 -0
  29. package/dist/src/commands/code/__tests__/fake-command-runner.js +5 -7
  30. package/dist/src/commands/code/__tests__/fake-file-store.js +9 -0
  31. package/dist/src/commands/code/__tests__/fake-prompter.js +60 -18
  32. package/dist/src/commands/code/__tests__/setup-flow.test.js +374 -107
  33. package/dist/src/commands/code/adapters/clack-prompter.js +10 -0
  34. package/dist/src/commands/code/adapters/fs-file-store.js +8 -3
  35. package/dist/src/commands/code/adapters/spawn-command-runner.js +15 -11
  36. package/dist/src/commands/code/auth-sync.js +283 -0
  37. package/dist/src/commands/code/errors.js +4 -4
  38. package/dist/src/commands/code/ports/auth-services.js +2 -0
  39. package/dist/src/commands/code/setup.js +234 -93
  40. package/dist/src/commands/code.js +139 -251
  41. package/dist/src/commands/models.js +13 -15
  42. package/dist/src/commands/users.js +6 -8
  43. package/dist/src/constants/command-structure.js +116 -116
  44. package/dist/src/services/api-key-service.js +43 -48
  45. package/dist/src/services/auth-service.js +60 -299
  46. package/dist/src/services/browser-auth.js +278 -0
  47. package/dist/src/services/chat-service.js +78 -91
  48. package/dist/src/services/cluster-service.js +6 -6
  49. package/dist/src/services/collaborator-service.js +5 -8
  50. package/dist/src/services/flux-service.js +5 -8
  51. package/dist/src/services/helm-service.js +5 -8
  52. package/dist/src/services/kubectl-service.js +7 -10
  53. package/dist/src/utils/config-checker.js +5 -5
  54. package/dist/src/utils/config-loader.js +25 -25
  55. package/dist/src/utils/default-api-key.js +23 -23
  56. package/dist/src/utils/env-manager.js +7 -7
  57. package/dist/src/utils/error-handler.js +60 -61
  58. package/dist/src/utils/logger.js +7 -7
  59. package/dist/src/utils/markdown-renderer.js +2 -2
  60. package/dist/src/utils/opencode-validator.js +17 -20
  61. package/dist/src/utils/token-manager.js +38 -11
  62. package/dist/tests/commands/chat.test.js +24 -24
  63. package/dist/tests/commands/code.test.js +147 -147
  64. package/dist/tests/utils/config-loader.test.js +114 -114
  65. package/dist/tests/utils/env-manager.test.js +57 -57
  66. package/dist/tests/utils/opencode-validator.test.js +33 -33
  67. package/dist/vitest.config.js +1 -1
  68. package/eslint.config.mjs +47 -0
  69. package/index.ts +42 -48
  70. package/package.json +28 -2
  71. package/src/agents/app.ts +27 -0
  72. package/src/agents/backend.ts +24 -0
  73. package/src/agents/devops.ts +33 -0
  74. package/src/agents/frontend.ts +24 -0
  75. package/src/agents/fullstack.ts +24 -0
  76. package/src/agents/index.ts +71 -0
  77. package/src/agents/quality.ts +69 -0
  78. package/src/agents/security.ts +26 -0
  79. package/src/agents/types.ts +17 -0
  80. package/src/client.ts +125 -167
  81. package/src/commands/api-keys.ts +261 -358
  82. package/src/commands/auth.ts +24 -30
  83. package/src/commands/autocomplete.ts +12 -12
  84. package/src/commands/billing.ts +22 -27
  85. package/src/commands/chat.ts +230 -323
  86. package/src/commands/clusters.ts +33 -33
  87. package/src/commands/code/__tests__/auth-sync.test.ts +481 -0
  88. package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
  89. package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
  90. package/src/commands/code/__tests__/fake-command-runner.ts +39 -42
  91. package/src/commands/code/__tests__/fake-file-store.ts +32 -23
  92. package/src/commands/code/__tests__/fake-prompter.ts +107 -69
  93. package/src/commands/code/__tests__/setup-flow.test.ts +624 -270
  94. package/src/commands/code/adapters/clack-prompter.ts +50 -38
  95. package/src/commands/code/adapters/fs-file-store.ts +31 -27
  96. package/src/commands/code/adapters/spawn-command-runner.ts +33 -29
  97. package/src/commands/code/auth-sync.ts +329 -0
  98. package/src/commands/code/errors.ts +15 -15
  99. package/src/commands/code/ports/auth-services.ts +14 -0
  100. package/src/commands/code/ports/command-runner.ts +8 -4
  101. package/src/commands/code/ports/file-store.ts +5 -4
  102. package/src/commands/code/ports/prompter.ts +24 -18
  103. package/src/commands/code/setup.ts +545 -317
  104. package/src/commands/code.ts +271 -473
  105. package/src/commands/index.ts +19 -19
  106. package/src/commands/models.ts +32 -37
  107. package/src/commands/users.ts +15 -22
  108. package/src/constants/command-structure.ts +119 -142
  109. package/src/services/api-key-service.ts +96 -113
  110. package/src/services/auth-service.ts +92 -339
  111. package/src/services/browser-auth.ts +296 -0
  112. package/src/services/chat-service.ts +246 -279
  113. package/src/services/cluster-service.ts +29 -32
  114. package/src/services/collaborator-service.ts +13 -18
  115. package/src/services/flux-service.ts +16 -18
  116. package/src/services/helm-service.ts +16 -18
  117. package/src/services/kubectl-service.ts +12 -14
  118. package/src/types/api.d.ts +924 -926
  119. package/src/types/json.d.ts +3 -3
  120. package/src/utils/config-checker.ts +10 -10
  121. package/src/utils/config-loader.ts +110 -127
  122. package/src/utils/default-api-key.ts +81 -93
  123. package/src/utils/env-manager.ts +36 -40
  124. package/src/utils/error-handler.ts +83 -78
  125. package/src/utils/logger.ts +41 -41
  126. package/src/utils/markdown-renderer.ts +11 -11
  127. package/src/utils/opencode-validator.ts +51 -56
  128. package/src/utils/token-manager.ts +84 -64
  129. package/templates/agents/app.md +1 -0
  130. package/templates/agents/backend.md +1 -0
  131. package/templates/agents/devops.md +2 -0
  132. package/templates/agents/frontend.md +1 -0
  133. package/templates/agents/fullstack.md +1 -0
  134. package/templates/agents/quality.md +45 -40
  135. package/templates/agents/security.md +1 -0
  136. package/tests/commands/chat.test.ts +60 -70
  137. package/tests/commands/code.test.ts +330 -376
  138. package/tests/utils/config-loader.test.ts +260 -260
  139. package/tests/utils/env-manager.test.ts +127 -134
  140. package/tests/utils/opencode-validator.test.ts +58 -63
  141. package/tsconfig.json +2 -2
  142. package/vitest.config.ts +3 -3
  143. package/AGENTS.md +0 -374
  144. package/TODO.md +0 -19
@@ -38,10 +38,10 @@ function confirm(question) {
38
38
  input: process.stdin,
39
39
  output: process.stdout,
40
40
  });
41
- return new Promise((resolve) => {
42
- rl.question(question, (answer) => {
41
+ return new Promise(resolve => {
42
+ rl.question(question, answer => {
43
43
  rl.close();
44
- resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
44
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
45
45
  });
46
46
  });
47
47
  });
@@ -50,19 +50,17 @@ function confirm(question) {
50
50
  * Register chat commands
51
51
  */
52
52
  function registerChatCommands(program) {
53
- const chat = program
54
- .command(command_structure_1.COMMAND_GROUPS.CHAT)
55
- .description('Interact with AI chat models');
53
+ const chat = program.command(command_structure_1.COMMAND_GROUPS.CHAT).description("Interact with AI chat models");
56
54
  chat
57
55
  .command(command_structure_1.SUBCOMMANDS.CHAT.RUN)
58
- .description('Run a chat session with a specified model')
59
- .argument('[message]', 'Message to send directly (skips interactive mode)')
60
- .option('-m, --model <model>', 'Model to use (default: glm-4.7)')
61
- .option('-t, --temperature <temp>', 'Temperature (0-1)', parseFloat)
62
- .option('--max-tokens <tokens>', 'Maximum tokens to generate', parseInt)
63
- .option('-k, --api-key <key>', 'API key to use for this chat session')
64
- .option('--api-key-id <id>', 'ID of the API key to use from your saved keys')
65
- .option('--no-stream', 'Disable streaming (streaming is enabled by default)')
56
+ .description("Run a chat session with a specified model")
57
+ .argument("[message]", "Message to send directly (skips interactive mode)")
58
+ .option("-m, --model <model>", "Model to use (default: glm-4.7)")
59
+ .option("-t, --temperature <temp>", "Temperature (0-1)", parseFloat)
60
+ .option("--max-tokens <tokens>", "Maximum tokens to generate", parseInt)
61
+ .option("-k, --api-key <key>", "API key to use for this chat session")
62
+ .option("--api-key-id <id>", "ID of the API key to use from your saved keys")
63
+ .option("--no-stream", "Disable streaming (streaming is enabled by default)")
66
64
  .action((message, options) => __awaiter(this, void 0, void 0, function* () {
67
65
  var _a, e_1, _b, _c;
68
66
  try {
@@ -76,7 +74,7 @@ function registerChatCommands(program) {
76
74
  console.log(chalk_1.default.dim(`Using API key from BERGET_API_KEY environment variable`));
77
75
  apiKey = envApiKey;
78
76
  // Debug the API key (first few characters only)
79
- if (process.argv.includes('--debug')) {
77
+ if (process.argv.includes("--debug")) {
80
78
  console.log(chalk_1.default.yellow(`DEBUG: API key from env starts with: ${envApiKey.substring(0, 4)}...`));
81
79
  }
82
80
  }
@@ -103,22 +101,22 @@ function registerChatCommands(program) {
103
101
  }
104
102
  else {
105
103
  // No default API key, prompt the user to create one
106
- console.log(chalk_1.default.yellow('No default API key set.'));
104
+ console.log(chalk_1.default.yellow("No default API key set."));
107
105
  // Try to prompt for a default API key
108
106
  apiKey = yield defaultApiKeyManager.promptForDefaultApiKey();
109
107
  if (!apiKey) {
110
- console.log(chalk_1.default.red('Error: An API key is required to use the chat command.'));
111
- console.log(chalk_1.default.yellow('You can:'));
108
+ console.log(chalk_1.default.red("Error: An API key is required to use the chat command."));
109
+ console.log(chalk_1.default.yellow("You can:"));
112
110
  console.log(chalk_1.default.yellow('1. Create an API key with: berget api-keys create --name "My Key"'));
113
- console.log(chalk_1.default.yellow('2. Set a default API key with: berget api-keys set-default <id>'));
114
- console.log(chalk_1.default.yellow('3. Provide an API key with the --api-key option'));
111
+ console.log(chalk_1.default.yellow("2. Set a default API key with: berget api-keys set-default <id>"));
112
+ console.log(chalk_1.default.yellow("3. Provide an API key with the --api-key option"));
115
113
  return;
116
114
  }
117
115
  }
118
116
  }
119
117
  catch (error) {
120
- if (process.argv.includes('--debug')) {
121
- console.log(chalk_1.default.yellow('DEBUG: Error checking default API key:'));
118
+ if (process.argv.includes("--debug")) {
119
+ console.log(chalk_1.default.yellow("DEBUG: Error checking default API key:"));
122
120
  console.log(chalk_1.default.yellow(String(error)));
123
121
  }
124
122
  }
@@ -128,7 +126,7 @@ function registerChatCommands(program) {
128
126
  try {
129
127
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
130
128
  const keys = yield apiKeyService.list();
131
- const selectedKey = keys.find((key) => key.id.toString() === options.apiKeyId);
129
+ const selectedKey = keys.find(key => key.id.toString() === options.apiKeyId);
132
130
  if (!selectedKey) {
133
131
  console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
134
132
  }
@@ -141,24 +139,24 @@ function registerChatCommands(program) {
141
139
  console.log(chalk_1.default.green(`API key "${selectedKey.name}" rotated successfully.`));
142
140
  }
143
141
  else {
144
- console.log(chalk_1.default.yellow('Using default authentication instead.'));
142
+ console.log(chalk_1.default.yellow("Using default authentication instead."));
145
143
  }
146
144
  }
147
145
  }
148
146
  catch (error) {
149
147
  // Check if this is an authentication error
150
148
  const errorMessage = error instanceof Error ? error.message : String(error);
151
- const isAuthError = errorMessage.includes('Unauthorized') ||
152
- errorMessage.includes('Authentication failed') ||
153
- errorMessage.includes('AUTH_FAILED');
149
+ const isAuthError = errorMessage.includes("Unauthorized") ||
150
+ errorMessage.includes("Authentication failed") ||
151
+ errorMessage.includes("AUTH_FAILED");
154
152
  if (isAuthError) {
155
- console.log(chalk_1.default.yellow('Authentication required. Please run `berget auth login` first.'));
153
+ console.log(chalk_1.default.yellow("Authentication required. Please run `berget auth login` first."));
156
154
  }
157
155
  else {
158
- console.error(chalk_1.default.red('Error fetching API key:'));
156
+ console.error(chalk_1.default.red("Error fetching API key:"));
159
157
  console.error(error);
160
158
  }
161
- console.log(chalk_1.default.yellow('Using default authentication instead.'));
159
+ console.log(chalk_1.default.yellow("Using default authentication instead."));
162
160
  }
163
161
  }
164
162
  // Verify we have authentication before starting chat
@@ -166,13 +164,13 @@ function registerChatCommands(program) {
166
164
  try {
167
165
  auth_service_1.AuthService.getInstance();
168
166
  }
169
- catch (error) {
170
- console.log(chalk_1.default.red('Error: Authentication required for chat'));
171
- console.log(chalk_1.default.yellow('Please either:'));
172
- console.log(chalk_1.default.yellow('1. Log in with `berget auth login`'));
173
- console.log(chalk_1.default.yellow('2. Provide an API key with `--api-key`'));
174
- console.log(chalk_1.default.yellow('3. Provide an API key ID with `--api-key-id`'));
175
- console.log(chalk_1.default.yellow('4. Set a default API key with `berget api-keys set-default <id>`'));
167
+ catch (_d) {
168
+ console.log(chalk_1.default.red("Error: Authentication required for chat"));
169
+ console.log(chalk_1.default.yellow("Please either:"));
170
+ console.log(chalk_1.default.yellow("1. Log in with `berget auth login`"));
171
+ console.log(chalk_1.default.yellow("2. Provide an API key with `--api-key`"));
172
+ console.log(chalk_1.default.yellow("3. Provide an API key ID with `--api-key-id`"));
173
+ console.log(chalk_1.default.yellow("4. Set a default API key with `berget api-keys set-default <id>`"));
176
174
  return;
177
175
  }
178
176
  }
@@ -181,20 +179,20 @@ function registerChatCommands(program) {
181
179
  // Add system message if provided
182
180
  if (options.system) {
183
181
  messages.push({
184
- role: 'system',
182
+ role: "system",
185
183
  content: options.system,
186
184
  });
187
185
  }
188
186
  // Check if input is being piped in
189
187
  let inputMessage = message;
190
- let stdinContent = '';
188
+ let stdinContent = "";
191
189
  if (!process.stdin.isTTY) {
192
190
  // Read from stdin (piped input)
193
191
  const chunks = [];
194
192
  try {
195
- for (var _d = true, _e = __asyncValues(process.stdin), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
196
- _c = _f.value;
197
- _d = false;
193
+ for (var _e = true, _f = __asyncValues(process.stdin), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) {
194
+ _c = _g.value;
195
+ _e = false;
198
196
  const chunk = _c;
199
197
  chunks.push(chunk);
200
198
  }
@@ -202,11 +200,11 @@ function registerChatCommands(program) {
202
200
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
203
201
  finally {
204
202
  try {
205
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
203
+ if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
206
204
  }
207
205
  finally { if (e_1) throw e_1.error; }
208
206
  }
209
- stdinContent = Buffer.concat(chunks).toString('utf8').trim();
207
+ stdinContent = Buffer.concat(chunks).toString("utf8").trim();
210
208
  }
211
209
  // Combine stdin content with message if both exist
212
210
  if (stdinContent && message) {
@@ -219,13 +217,13 @@ function registerChatCommands(program) {
219
217
  if (inputMessage) {
220
218
  // Add user message
221
219
  messages.push({
222
- role: 'user',
220
+ role: "user",
223
221
  content: inputMessage,
224
222
  });
225
223
  try {
226
224
  // Call the API
227
225
  const completionOptions = {
228
- model: options.model || 'openai/gpt-oss',
226
+ model: options.model || "openai/gpt-oss",
229
227
  messages: messages,
230
228
  temperature: options.temperature !== undefined ? options.temperature : 0.7,
231
229
  max_tokens: options.maxTokens || 4096,
@@ -237,7 +235,7 @@ function registerChatCommands(program) {
237
235
  }
238
236
  // Add streaming support (now default)
239
237
  if (completionOptions.stream) {
240
- let assistantResponse = '';
238
+ let assistantResponse = "";
241
239
  // Stream the response in real-time
242
240
  completionOptions.onChunk = (chunk) => {
243
241
  if (chunk.choices &&
@@ -250,7 +248,7 @@ function registerChatCommands(program) {
250
248
  }
251
249
  catch (error) {
252
250
  // Handle EPIPE errors gracefully (when pipe is closed)
253
- if (error.code === 'EPIPE') {
251
+ if (error.code === "EPIPE") {
254
252
  // Stop streaming if the pipe is closed
255
253
  return;
256
254
  }
@@ -263,9 +261,9 @@ function registerChatCommands(program) {
263
261
  yield chatService.createCompletion(completionOptions);
264
262
  }
265
263
  catch (streamError) {
266
- console.error(chalk_1.default.red('\nStreaming error:'), streamError);
264
+ console.error(chalk_1.default.red("\nStreaming error:"), streamError);
267
265
  // Fallback to non-streaming if streaming fails
268
- console.log(chalk_1.default.yellow('Falling back to non-streaming mode...'));
266
+ console.log(chalk_1.default.yellow("Falling back to non-streaming mode..."));
269
267
  completionOptions.stream = false;
270
268
  delete completionOptions.onChunk;
271
269
  const response = yield chatService.createCompletion(completionOptions);
@@ -286,9 +284,9 @@ function registerChatCommands(program) {
286
284
  !response.choices ||
287
285
  !response.choices[0] ||
288
286
  !response.choices[0].message) {
289
- console.error(chalk_1.default.red('Error: Unexpected response format from API'));
290
- console.error(chalk_1.default.red('Response:', JSON.stringify(response, null, 2)));
291
- throw new Error('Unexpected response format from API');
287
+ console.error(chalk_1.default.red("Error: Unexpected response format from API"));
288
+ console.error(chalk_1.default.red("Response:", JSON.stringify(response, null, 2)));
289
+ throw new Error("Unexpected response format from API");
292
290
  }
293
291
  // Get assistant's response
294
292
  const assistantMessage = response.choices[0].message.content;
@@ -302,7 +300,7 @@ function registerChatCommands(program) {
302
300
  return;
303
301
  }
304
302
  catch (error) {
305
- console.error(chalk_1.default.red('Error: Failed to get response'));
303
+ console.error(chalk_1.default.red("Error: Failed to get response"));
306
304
  if (error instanceof Error) {
307
305
  console.error(chalk_1.default.red(error.message));
308
306
  }
@@ -315,25 +313,25 @@ function registerChatCommands(program) {
315
313
  output: process.stdout,
316
314
  });
317
315
  console.log(chalk_1.default.cyan('Chat with Berget AI (type "exit" to quit)'));
318
- console.log(chalk_1.default.cyan('----------------------------------------'));
316
+ console.log(chalk_1.default.cyan("----------------------------------------"));
319
317
  // Start the conversation loop
320
318
  const askQuestion = () => {
321
- rl.question(chalk_1.default.green('You: '), (input) => __awaiter(this, void 0, void 0, function* () {
319
+ rl.question(chalk_1.default.green("You: "), (input) => __awaiter(this, void 0, void 0, function* () {
322
320
  // Check if user wants to exit
323
- if (input.toLowerCase() === 'exit') {
324
- console.log(chalk_1.default.cyan('Goodbye!'));
321
+ if (input.toLowerCase() === "exit") {
322
+ console.log(chalk_1.default.cyan("Goodbye!"));
325
323
  rl.close();
326
324
  return;
327
325
  }
328
326
  // Add user message
329
327
  messages.push({
330
- role: 'user',
328
+ role: "user",
331
329
  content: input,
332
330
  });
333
331
  try {
334
332
  // Call the API
335
333
  const completionOptions = {
336
- model: options.model || 'openai/gpt-oss',
334
+ model: options.model || "openai/gpt-oss",
337
335
  messages: messages,
338
336
  temperature: options.temperature !== undefined ? options.temperature : 0.7,
339
337
  max_tokens: options.maxTokens || 4096,
@@ -345,8 +343,8 @@ function registerChatCommands(program) {
345
343
  }
346
344
  // Add streaming support (now default)
347
345
  if (completionOptions.stream) {
348
- let assistantResponse = '';
349
- console.log(chalk_1.default.blue('Assistant: '));
346
+ let assistantResponse = "";
347
+ console.log(chalk_1.default.blue("Assistant: "));
350
348
  // Stream the response in real-time
351
349
  completionOptions.onChunk = (chunk) => {
352
350
  if (chunk.choices &&
@@ -359,7 +357,7 @@ function registerChatCommands(program) {
359
357
  }
360
358
  catch (error) {
361
359
  // Handle EPIPE errors gracefully (when pipe is closed)
362
- if (error.code === 'EPIPE') {
360
+ if (error.code === "EPIPE") {
363
361
  // Stop streaming if the pipe is closed
364
362
  return;
365
363
  }
@@ -372,9 +370,9 @@ function registerChatCommands(program) {
372
370
  yield chatService.createCompletion(completionOptions);
373
371
  }
374
372
  catch (streamError) {
375
- console.error(chalk_1.default.red('\nStreaming error:'), streamError);
373
+ console.error(chalk_1.default.red("\nStreaming error:"), streamError);
376
374
  // Fallback to non-streaming if streaming fails
377
- console.log(chalk_1.default.yellow('Falling back to non-streaming mode...'));
375
+ console.log(chalk_1.default.yellow("Falling back to non-streaming mode..."));
378
376
  completionOptions.stream = false;
379
377
  delete completionOptions.onChunk;
380
378
  const response = yield chatService.createCompletion(completionOptions);
@@ -386,10 +384,10 @@ function registerChatCommands(program) {
386
384
  console.log(assistantResponse);
387
385
  }
388
386
  }
389
- console.log('\n');
387
+ console.log("\n");
390
388
  // Add assistant response to messages
391
389
  messages.push({
392
- role: 'assistant',
390
+ role: "assistant",
393
391
  content: assistantResponse,
394
392
  });
395
393
  // Continue the conversation
@@ -399,7 +397,7 @@ function registerChatCommands(program) {
399
397
  const response = yield chatService.createCompletion(completionOptions);
400
398
  // Debug output
401
399
  if (program.opts().debug) {
402
- console.log(chalk_1.default.yellow('DEBUG: Full response:'));
400
+ console.log(chalk_1.default.yellow("DEBUG: Full response:"));
403
401
  console.log(chalk_1.default.yellow(JSON.stringify(response, null, 2)));
404
402
  }
405
403
  // Check if response has the expected structure
@@ -407,19 +405,19 @@ function registerChatCommands(program) {
407
405
  !response.choices ||
408
406
  !response.choices[0] ||
409
407
  !response.choices[0].message) {
410
- console.error(chalk_1.default.red('Error: Unexpected response format from API'));
411
- console.error(chalk_1.default.red('Response:', JSON.stringify(response, null, 2)));
412
- throw new Error('Unexpected response format from API');
408
+ console.error(chalk_1.default.red("Error: Unexpected response format from API"));
409
+ console.error(chalk_1.default.red("Response:", JSON.stringify(response, null, 2)));
410
+ throw new Error("Unexpected response format from API");
413
411
  }
414
412
  // Get assistant's response
415
413
  const assistantMessage = response.choices[0].message.content;
416
414
  // Add to messages array
417
415
  messages.push({
418
- role: 'assistant',
416
+ role: "assistant",
419
417
  content: assistantMessage,
420
418
  });
421
419
  // Display the response
422
- console.log(chalk_1.default.blue('Assistant: '));
420
+ console.log(chalk_1.default.blue("Assistant: "));
423
421
  // Check if the response contains markdown and render it if it does
424
422
  if ((0, markdown_renderer_1.containsMarkdown)(assistantMessage)) {
425
423
  console.log((0, markdown_renderer_1.renderMarkdown)(assistantMessage));
@@ -432,7 +430,7 @@ function registerChatCommands(program) {
432
430
  askQuestion();
433
431
  }
434
432
  catch (error) {
435
- console.error(chalk_1.default.red('Error: Failed to get response'));
433
+ console.error(chalk_1.default.red("Error: Failed to get response"));
436
434
  if (error instanceof Error) {
437
435
  console.error(chalk_1.default.red(error.message));
438
436
  }
@@ -445,14 +443,14 @@ function registerChatCommands(program) {
445
443
  askQuestion();
446
444
  }
447
445
  catch (error) {
448
- (0, error_handler_1.handleError)('Failed to create chat completion', error);
446
+ (0, error_handler_1.handleError)("Failed to create chat completion", error);
449
447
  }
450
448
  }));
451
449
  chat
452
450
  .command(command_structure_1.SUBCOMMANDS.CHAT.LIST)
453
- .description('List available chat models')
454
- .option('-k, --api-key <key>', 'API key to use for this request')
455
- .option('--api-key-id <id>', 'ID of the API key to use from your saved keys')
451
+ .description("List available chat models")
452
+ .option("-k, --api-key <key>", "API key to use for this request")
453
+ .option("--api-key-id <id>", "ID of the API key to use from your saved keys")
456
454
  .action((options) => __awaiter(this, void 0, void 0, function* () {
457
455
  try {
458
456
  // If API key ID is provided, fetch the actual key
@@ -471,7 +469,7 @@ function registerChatCommands(program) {
471
469
  try {
472
470
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
473
471
  const keys = yield apiKeyService.list();
474
- const selectedKey = keys.find((key) => key.id.toString() === options.apiKeyId);
472
+ const selectedKey = keys.find(key => key.id.toString() === options.apiKeyId);
475
473
  if (!selectedKey) {
476
474
  console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
477
475
  }
@@ -484,44 +482,44 @@ function registerChatCommands(program) {
484
482
  console.log(chalk_1.default.green(`API key "${selectedKey.name}" rotated successfully.`));
485
483
  }
486
484
  else {
487
- console.log(chalk_1.default.yellow('Using default authentication instead.'));
485
+ console.log(chalk_1.default.yellow("Using default authentication instead."));
488
486
  }
489
487
  }
490
488
  }
491
489
  catch (error) {
492
- console.error(chalk_1.default.red('Error fetching API key:'));
490
+ console.error(chalk_1.default.red("Error fetching API key:"));
493
491
  console.error(error);
494
- console.log(chalk_1.default.yellow('Using default authentication instead.'));
492
+ console.log(chalk_1.default.yellow("Using default authentication instead."));
495
493
  }
496
494
  }
497
495
  const chatService = chat_service_1.ChatService.getInstance();
498
496
  const models = yield chatService.listModels(apiKey);
499
497
  // Debug output
500
498
  if (program.opts().debug) {
501
- console.log(chalk_1.default.yellow('DEBUG: Models response:'));
499
+ console.log(chalk_1.default.yellow("DEBUG: Models response:"));
502
500
  console.log(chalk_1.default.yellow(JSON.stringify(models, null, 2)));
503
501
  }
504
- console.log(chalk_1.default.bold('Available Chat Models:'));
505
- console.log(chalk_1.default.dim(''.repeat(70)));
506
- console.log(chalk_1.default.dim('MODEL ID'.padEnd(40)) + chalk_1.default.dim('CAPABILITIES'));
507
- console.log(chalk_1.default.dim(''.repeat(70)));
502
+ console.log(chalk_1.default.bold("Available Chat Models:"));
503
+ console.log(chalk_1.default.dim("".repeat(70)));
504
+ console.log(chalk_1.default.dim("MODEL ID".padEnd(40)) + chalk_1.default.dim("CAPABILITIES"));
505
+ console.log(chalk_1.default.dim("".repeat(70)));
508
506
  // Filter to only show active models
509
507
  const activeModels = models.data.filter((model) => model.active === true);
510
508
  activeModels.forEach((model) => {
511
509
  const capabilities = [];
512
510
  if (model.capabilities.vision)
513
- capabilities.push('vision');
511
+ capabilities.push("vision");
514
512
  if (model.capabilities.function_calling)
515
- capabilities.push('function_calling');
513
+ capabilities.push("function_calling");
516
514
  if (model.capabilities.json_mode)
517
- capabilities.push('json_mode');
515
+ capabilities.push("json_mode");
518
516
  // Format model ID in Huggingface compatible format (owner/model)
519
517
  const modelId = `${model.owned_by.toLowerCase()}/${model.id}`.padEnd(40);
520
- console.log(modelId + capabilities.join(', '));
518
+ console.log(modelId + capabilities.join(", "));
521
519
  });
522
520
  }
523
521
  catch (error) {
524
- (0, error_handler_1.handleError)('Failed to list chat models', error);
522
+ (0, error_handler_1.handleError)("Failed to list chat models", error);
525
523
  }
526
524
  }));
527
525
  }
@@ -18,51 +18,51 @@ const error_handler_1 = require("../utils/error-handler");
18
18
  function registerClusterCommands(program) {
19
19
  const cluster = program
20
20
  .command(cluster_service_1.ClusterService.COMMAND_GROUP)
21
- .description('Manage Berget clusters');
21
+ .description("Manage Berget clusters");
22
22
  cluster
23
23
  .command(cluster_service_1.ClusterService.COMMANDS.LIST)
24
- .description('List all Berget clusters')
24
+ .description("List all Berget clusters")
25
25
  .action(() => __awaiter(this, void 0, void 0, function* () {
26
26
  try {
27
27
  const clusterService = cluster_service_1.ClusterService.getInstance();
28
28
  const clusters = yield clusterService.list();
29
- console.log('NAME STATUS NODES CREATED');
29
+ console.log("NAME STATUS NODES CREATED");
30
30
  clusters.forEach((cluster) => {
31
31
  console.log(`${cluster.name.padEnd(22)} ${cluster.status.padEnd(9)} ${String(cluster.nodes).padEnd(8)} ${cluster.created}`);
32
32
  });
33
33
  }
34
34
  catch (error) {
35
- (0, error_handler_1.handleError)('Failed to list clusters', error);
35
+ (0, error_handler_1.handleError)("Failed to list clusters", error);
36
36
  }
37
37
  }));
38
38
  cluster
39
39
  .command(cluster_service_1.ClusterService.COMMANDS.GET_USAGE)
40
- .description('Get usage metrics for a specific cluster')
41
- .argument('<clusterId>', 'Cluster ID')
40
+ .description("Get usage metrics for a specific cluster")
41
+ .argument("<clusterId>", "Cluster ID")
42
42
  .action((clusterId) => __awaiter(this, void 0, void 0, function* () {
43
43
  try {
44
44
  const clusterService = cluster_service_1.ClusterService.getInstance();
45
45
  const usage = yield clusterService.getUsage(clusterId);
46
- console.log('Cluster Usage:');
46
+ console.log("Cluster Usage:");
47
47
  console.log(JSON.stringify(usage, null, 2));
48
48
  }
49
49
  catch (error) {
50
- (0, error_handler_1.handleError)('Failed to get cluster usage', error);
50
+ (0, error_handler_1.handleError)("Failed to get cluster usage", error);
51
51
  }
52
52
  }));
53
53
  cluster
54
54
  .command(cluster_service_1.ClusterService.COMMANDS.DESCRIBE)
55
- .description('Get detailed information about a cluster')
56
- .argument('<clusterId>', 'Cluster ID')
55
+ .description("Get detailed information about a cluster")
56
+ .argument("<clusterId>", "Cluster ID")
57
57
  .action((clusterId) => __awaiter(this, void 0, void 0, function* () {
58
58
  try {
59
59
  const clusterService = cluster_service_1.ClusterService.getInstance();
60
60
  const clusterInfo = yield clusterService.describe(clusterId);
61
- console.log('Cluster Details:');
61
+ console.log("Cluster Details:");
62
62
  console.log(JSON.stringify(clusterInfo, null, 2));
63
63
  }
64
64
  catch (error) {
65
- (0, error_handler_1.handleError)('Failed to describe cluster', error);
65
+ (0, error_handler_1.handleError)("Failed to describe cluster", error);
66
66
  }
67
67
  }));
68
68
  }