berget 2.2.7 → 2.2.8

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 +5 -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 +195 -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 +7 -7
  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 +50 -30
  64. package/index.ts +30 -31
  65. package/package.json +5 -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 +190 -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 +169 -170
  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 +6 -6
  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,81 +1,47 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __asyncValues = (this && this.__asyncValues) || function (o) {
12
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
- var m = o[Symbol.asyncIterator], i;
14
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
- };
18
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
19
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
20
4
  };
21
5
  Object.defineProperty(exports, "__esModule", { value: true });
22
6
  exports.registerChatCommands = void 0;
23
7
  const chalk_1 = __importDefault(require("chalk"));
24
- const readline_1 = __importDefault(require("readline"));
8
+ const node_readline_1 = __importDefault(require("node:readline"));
25
9
  const command_structure_1 = require("../constants/command-structure");
26
- const chat_service_1 = require("../services/chat-service");
27
10
  const api_key_service_1 = require("../services/api-key-service");
28
11
  const auth_service_1 = require("../services/auth-service");
29
- const error_handler_1 = require("../utils/error-handler");
12
+ const chat_service_1 = require("../services/chat-service");
30
13
  const default_api_key_1 = require("../utils/default-api-key");
14
+ const error_handler_1 = require("../utils/error-handler");
31
15
  const markdown_renderer_1 = require("../utils/markdown-renderer");
32
- /**
33
- * Helper function to get user confirmation
34
- */
35
- function confirm(question) {
36
- return __awaiter(this, void 0, void 0, function* () {
37
- const rl = readline_1.default.createInterface({
38
- input: process.stdin,
39
- output: process.stdout,
40
- });
41
- return new Promise(resolve => {
42
- rl.question(question, answer => {
43
- rl.close();
44
- resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
45
- });
46
- });
47
- });
48
- }
49
16
  /**
50
17
  * Register chat commands
51
18
  */
52
19
  function registerChatCommands(program) {
53
- const chat = program.command(command_structure_1.COMMAND_GROUPS.CHAT).description("Interact with AI chat models");
20
+ const chat = program.command(command_structure_1.COMMAND_GROUPS.CHAT).description('Interact with AI chat models');
54
21
  chat
55
22
  .command(command_structure_1.SUBCOMMANDS.CHAT.RUN)
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)")
64
- .action((message, options) => __awaiter(this, void 0, void 0, function* () {
65
- var _a, e_1, _b, _c;
23
+ .description('Run a chat session with a specified model')
24
+ .argument('[message]', 'Message to send directly (skips interactive mode)')
25
+ .option('-m, --model <model>', 'Model to use (default: glm-4.7)')
26
+ .option('-t, --temperature <temp>', 'Temperature (0-1)', Number.parseFloat)
27
+ .option('--max-tokens <tokens>', 'Maximum tokens to generate', Number.parseInt)
28
+ .option('-k, --api-key <key>', 'API key to use for this chat session')
29
+ .option('--api-key-id <id>', 'ID of the API key to use from your saved keys')
30
+ .option('--no-stream', 'Disable streaming (streaming is enabled by default)')
31
+ .action(async (message, options) => {
66
32
  try {
67
33
  const chatService = chat_service_1.ChatService.getInstance();
68
34
  // Check if we have an API key or need to get one
69
35
  let apiKey = options.apiKey;
70
36
  let apiKeyId = options.apiKeyId;
71
37
  // Check for environment variable first
72
- const envApiKey = process.env.BERGET_API_KEY;
73
- if (envApiKey) {
38
+ const environmentApiKey = process.env.BERGET_API_KEY;
39
+ if (environmentApiKey) {
74
40
  console.log(chalk_1.default.dim(`Using API key from BERGET_API_KEY environment variable`));
75
- apiKey = envApiKey;
41
+ apiKey = environmentApiKey;
76
42
  // Debug the API key (first few characters only)
77
- if (process.argv.includes("--debug")) {
78
- console.log(chalk_1.default.yellow(`DEBUG: API key from env starts with: ${envApiKey.substring(0, 4)}...`));
43
+ if (process.argv.includes('--debug')) {
44
+ console.log(chalk_1.default.yellow(`DEBUG: API key from env starts with: ${environmentApiKey.slice(0, 4)}...`));
79
45
  }
80
46
  }
81
47
  // If API key is already provided via command line, use it
@@ -101,22 +67,22 @@ function registerChatCommands(program) {
101
67
  }
102
68
  else {
103
69
  // No default API key, prompt the user to create one
104
- console.log(chalk_1.default.yellow("No default API key set."));
70
+ console.log(chalk_1.default.yellow('No default API key set.'));
105
71
  // Try to prompt for a default API key
106
- apiKey = yield defaultApiKeyManager.promptForDefaultApiKey();
72
+ apiKey = await defaultApiKeyManager.promptForDefaultApiKey();
107
73
  if (!apiKey) {
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:"));
74
+ console.log(chalk_1.default.red('Error: An API key is required to use the chat command.'));
75
+ console.log(chalk_1.default.yellow('You can:'));
110
76
  console.log(chalk_1.default.yellow('1. Create an API key with: berget api-keys create --name "My Key"'));
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"));
77
+ console.log(chalk_1.default.yellow('2. Set a default API key with: berget api-keys set-default <id>'));
78
+ console.log(chalk_1.default.yellow('3. Provide an API key with the --api-key option'));
113
79
  return;
114
80
  }
115
81
  }
116
82
  }
117
83
  catch (error) {
118
- if (process.argv.includes("--debug")) {
119
- console.log(chalk_1.default.yellow("DEBUG: Error checking default API key:"));
84
+ if (process.argv.includes('--debug')) {
85
+ console.log(chalk_1.default.yellow('DEBUG: Error checking default API key:'));
120
86
  console.log(chalk_1.default.yellow(String(error)));
121
87
  }
122
88
  }
@@ -125,38 +91,38 @@ function registerChatCommands(program) {
125
91
  if (!apiKey && apiKeyId) {
126
92
  try {
127
93
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
128
- const keys = yield apiKeyService.list();
129
- const selectedKey = keys.find(key => key.id.toString() === options.apiKeyId);
130
- if (!selectedKey) {
131
- console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
132
- }
133
- else {
94
+ const keys = await apiKeyService.list();
95
+ const selectedKey = keys.find((key) => key.id.toString() === options.apiKeyId);
96
+ if (selectedKey) {
134
97
  console.log(chalk_1.default.dim(`Using API key: ${selectedKey.name}`));
135
98
  // We need to rotate the key to get the actual key value
136
- if (yield confirm(chalk_1.default.yellow(`To use API key "${selectedKey.name}", it needs to be rotated. This will invalidate the current key. Continue? (y/n)`))) {
137
- const rotatedKey = yield apiKeyService.rotate(options.apiKeyId);
99
+ if (await confirm(chalk_1.default.yellow(`To use API key "${selectedKey.name}", it needs to be rotated. This will invalidate the current key. Continue? (y/n)`))) {
100
+ const rotatedKey = await apiKeyService.rotate(options.apiKeyId);
138
101
  apiKey = rotatedKey.key;
139
102
  console.log(chalk_1.default.green(`API key "${selectedKey.name}" rotated successfully.`));
140
103
  }
141
104
  else {
142
- console.log(chalk_1.default.yellow("Using default authentication instead."));
105
+ console.log(chalk_1.default.yellow('Using default authentication instead.'));
143
106
  }
144
107
  }
108
+ else {
109
+ console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
110
+ }
145
111
  }
146
112
  catch (error) {
147
113
  // Check if this is an authentication error
148
114
  const errorMessage = error instanceof Error ? error.message : String(error);
149
- const isAuthError = errorMessage.includes("Unauthorized") ||
150
- errorMessage.includes("Authentication failed") ||
151
- errorMessage.includes("AUTH_FAILED");
115
+ const isAuthError = errorMessage.includes('Unauthorized') ||
116
+ errorMessage.includes('Authentication failed') ||
117
+ errorMessage.includes('AUTH_FAILED');
152
118
  if (isAuthError) {
153
- console.log(chalk_1.default.yellow("Authentication required. Please run `berget auth login` first."));
119
+ console.log(chalk_1.default.yellow('Authentication required. Please run `berget auth login` first.'));
154
120
  }
155
121
  else {
156
- console.error(chalk_1.default.red("Error fetching API key:"));
122
+ console.error(chalk_1.default.red('Error fetching API key:'));
157
123
  console.error(error);
158
124
  }
159
- console.log(chalk_1.default.yellow("Using default authentication instead."));
125
+ console.log(chalk_1.default.yellow('Using default authentication instead.'));
160
126
  }
161
127
  }
162
128
  // Verify we have authentication before starting chat
@@ -164,13 +130,13 @@ function registerChatCommands(program) {
164
130
  try {
165
131
  auth_service_1.AuthService.getInstance();
166
132
  }
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>`"));
133
+ catch {
134
+ console.log(chalk_1.default.red('Error: Authentication required for chat'));
135
+ console.log(chalk_1.default.yellow('Please either:'));
136
+ console.log(chalk_1.default.yellow('1. Log in with `berget auth login`'));
137
+ console.log(chalk_1.default.yellow('2. Provide an API key with `--api-key`'));
138
+ console.log(chalk_1.default.yellow('3. Provide an API key ID with `--api-key-id`'));
139
+ console.log(chalk_1.default.yellow('4. Set a default API key with `berget api-keys set-default <id>`'));
174
140
  return;
175
141
  }
176
142
  }
@@ -179,32 +145,20 @@ function registerChatCommands(program) {
179
145
  // Add system message if provided
180
146
  if (options.system) {
181
147
  messages.push({
182
- role: "system",
183
148
  content: options.system,
149
+ role: 'system',
184
150
  });
185
151
  }
186
152
  // Check if input is being piped in
187
153
  let inputMessage = message;
188
- let stdinContent = "";
154
+ let stdinContent = '';
189
155
  if (!process.stdin.isTTY) {
190
156
  // Read from stdin (piped input)
191
157
  const chunks = [];
192
- try {
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;
196
- const chunk = _c;
197
- chunks.push(chunk);
198
- }
158
+ for await (const chunk of process.stdin) {
159
+ chunks.push(chunk);
199
160
  }
200
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
201
- finally {
202
- try {
203
- if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
204
- }
205
- finally { if (e_1) throw e_1.error; }
206
- }
207
- stdinContent = Buffer.concat(chunks).toString("utf8").trim();
161
+ stdinContent = Buffer.concat(chunks).toString('utf8').trim();
208
162
  }
209
163
  // Combine stdin content with message if both exist
210
164
  if (stdinContent && message) {
@@ -217,17 +171,17 @@ function registerChatCommands(program) {
217
171
  if (inputMessage) {
218
172
  // Add user message
219
173
  messages.push({
220
- role: "user",
221
174
  content: inputMessage,
175
+ role: 'user',
222
176
  });
223
177
  try {
224
178
  // Call the API
225
179
  const completionOptions = {
226
- model: options.model || "openai/gpt-oss",
227
- messages: messages,
228
- temperature: options.temperature !== undefined ? options.temperature : 0.7,
229
180
  max_tokens: options.maxTokens || 4096,
181
+ messages: messages,
182
+ model: options.model || 'openai/gpt-oss',
230
183
  stream: options.stream !== false,
184
+ temperature: options.temperature === undefined ? 0.7 : options.temperature,
231
185
  };
232
186
  // Only add apiKey if it actually exists
233
187
  if (apiKey) {
@@ -235,7 +189,7 @@ function registerChatCommands(program) {
235
189
  }
236
190
  // Add streaming support (now default)
237
191
  if (completionOptions.stream) {
238
- let assistantResponse = "";
192
+ let assistantResponse = '';
239
193
  // Stream the response in real-time
240
194
  completionOptions.onChunk = (chunk) => {
241
195
  if (chunk.choices &&
@@ -248,7 +202,7 @@ function registerChatCommands(program) {
248
202
  }
249
203
  catch (error) {
250
204
  // Handle EPIPE errors gracefully (when pipe is closed)
251
- if (error.code === "EPIPE") {
205
+ if (error.code === 'EPIPE') {
252
206
  // Stop streaming if the pipe is closed
253
207
  return;
254
208
  }
@@ -258,15 +212,15 @@ function registerChatCommands(program) {
258
212
  }
259
213
  };
260
214
  try {
261
- yield chatService.createCompletion(completionOptions);
215
+ await chatService.createCompletion(completionOptions);
262
216
  }
263
217
  catch (streamError) {
264
- console.error(chalk_1.default.red("\nStreaming error:"), streamError);
218
+ console.error(chalk_1.default.red('\nStreaming error:'), streamError);
265
219
  // Fallback to non-streaming if streaming fails
266
- console.log(chalk_1.default.yellow("Falling back to non-streaming mode..."));
220
+ console.log(chalk_1.default.yellow('Falling back to non-streaming mode...'));
267
221
  completionOptions.stream = false;
268
222
  delete completionOptions.onChunk;
269
- const response = yield chatService.createCompletion(completionOptions);
223
+ const response = await chatService.createCompletion(completionOptions);
270
224
  if (response &&
271
225
  response.choices &&
272
226
  response.choices[0] &&
@@ -278,15 +232,15 @@ function registerChatCommands(program) {
278
232
  console.log(); // Add newline at the end
279
233
  return;
280
234
  }
281
- const response = yield chatService.createCompletion(completionOptions);
235
+ const response = await chatService.createCompletion(completionOptions);
282
236
  // Check if response has the expected structure
283
237
  if (!response ||
284
238
  !response.choices ||
285
239
  !response.choices[0] ||
286
240
  !response.choices[0].message) {
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");
241
+ console.error(chalk_1.default.red('Error: Unexpected response format from API'));
242
+ console.error(chalk_1.default.red('Response:', JSON.stringify(response, null, 2)));
243
+ throw new Error('Unexpected response format from API');
290
244
  }
291
245
  // Get assistant's response
292
246
  const assistantMessage = response.choices[0].message.content;
@@ -300,7 +254,7 @@ function registerChatCommands(program) {
300
254
  return;
301
255
  }
302
256
  catch (error) {
303
- console.error(chalk_1.default.red("Error: Failed to get response"));
257
+ console.error(chalk_1.default.red('Error: Failed to get response'));
304
258
  if (error instanceof Error) {
305
259
  console.error(chalk_1.default.red(error.message));
306
260
  }
@@ -308,34 +262,34 @@ function registerChatCommands(program) {
308
262
  }
309
263
  }
310
264
  // Set up readline interface for user input (only for interactive mode)
311
- const rl = readline_1.default.createInterface({
265
+ const rl = node_readline_1.default.createInterface({
312
266
  input: process.stdin,
313
267
  output: process.stdout,
314
268
  });
315
269
  console.log(chalk_1.default.cyan('Chat with Berget AI (type "exit" to quit)'));
316
- console.log(chalk_1.default.cyan("----------------------------------------"));
270
+ console.log(chalk_1.default.cyan('----------------------------------------'));
317
271
  // Start the conversation loop
318
272
  const askQuestion = () => {
319
- rl.question(chalk_1.default.green("You: "), (input) => __awaiter(this, void 0, void 0, function* () {
273
+ rl.question(chalk_1.default.green('You: '), async (input) => {
320
274
  // Check if user wants to exit
321
- if (input.toLowerCase() === "exit") {
322
- console.log(chalk_1.default.cyan("Goodbye!"));
275
+ if (input.toLowerCase() === 'exit') {
276
+ console.log(chalk_1.default.cyan('Goodbye!'));
323
277
  rl.close();
324
278
  return;
325
279
  }
326
280
  // Add user message
327
281
  messages.push({
328
- role: "user",
329
282
  content: input,
283
+ role: 'user',
330
284
  });
331
285
  try {
332
286
  // Call the API
333
287
  const completionOptions = {
334
- model: options.model || "openai/gpt-oss",
335
- messages: messages,
336
- temperature: options.temperature !== undefined ? options.temperature : 0.7,
337
288
  max_tokens: options.maxTokens || 4096,
289
+ messages: messages,
290
+ model: options.model || 'openai/gpt-oss',
338
291
  stream: options.stream !== false,
292
+ temperature: options.temperature === undefined ? 0.7 : options.temperature,
339
293
  };
340
294
  // Only add apiKey if it actually exists
341
295
  if (apiKey) {
@@ -343,8 +297,8 @@ function registerChatCommands(program) {
343
297
  }
344
298
  // Add streaming support (now default)
345
299
  if (completionOptions.stream) {
346
- let assistantResponse = "";
347
- console.log(chalk_1.default.blue("Assistant: "));
300
+ let assistantResponse = '';
301
+ console.log(chalk_1.default.blue('Assistant: '));
348
302
  // Stream the response in real-time
349
303
  completionOptions.onChunk = (chunk) => {
350
304
  if (chunk.choices &&
@@ -357,7 +311,7 @@ function registerChatCommands(program) {
357
311
  }
358
312
  catch (error) {
359
313
  // Handle EPIPE errors gracefully (when pipe is closed)
360
- if (error.code === "EPIPE") {
314
+ if (error.code === 'EPIPE') {
361
315
  // Stop streaming if the pipe is closed
362
316
  return;
363
317
  }
@@ -367,15 +321,15 @@ function registerChatCommands(program) {
367
321
  }
368
322
  };
369
323
  try {
370
- yield chatService.createCompletion(completionOptions);
324
+ await chatService.createCompletion(completionOptions);
371
325
  }
372
326
  catch (streamError) {
373
- console.error(chalk_1.default.red("\nStreaming error:"), streamError);
327
+ console.error(chalk_1.default.red('\nStreaming error:'), streamError);
374
328
  // Fallback to non-streaming if streaming fails
375
- console.log(chalk_1.default.yellow("Falling back to non-streaming mode..."));
329
+ console.log(chalk_1.default.yellow('Falling back to non-streaming mode...'));
376
330
  completionOptions.stream = false;
377
331
  delete completionOptions.onChunk;
378
- const response = yield chatService.createCompletion(completionOptions);
332
+ const response = await chatService.createCompletion(completionOptions);
379
333
  if (response &&
380
334
  response.choices &&
381
335
  response.choices[0] &&
@@ -384,20 +338,20 @@ function registerChatCommands(program) {
384
338
  console.log(assistantResponse);
385
339
  }
386
340
  }
387
- console.log("\n");
341
+ console.log('\n');
388
342
  // Add assistant response to messages
389
343
  messages.push({
390
- role: "assistant",
391
344
  content: assistantResponse,
345
+ role: 'assistant',
392
346
  });
393
347
  // Continue the conversation
394
348
  askQuestion();
395
349
  return;
396
350
  }
397
- const response = yield chatService.createCompletion(completionOptions);
351
+ const response = await chatService.createCompletion(completionOptions);
398
352
  // Debug output
399
353
  if (program.opts().debug) {
400
- console.log(chalk_1.default.yellow("DEBUG: Full response:"));
354
+ console.log(chalk_1.default.yellow('DEBUG: Full response:'));
401
355
  console.log(chalk_1.default.yellow(JSON.stringify(response, null, 2)));
402
356
  }
403
357
  // Check if response has the expected structure
@@ -405,19 +359,19 @@ function registerChatCommands(program) {
405
359
  !response.choices ||
406
360
  !response.choices[0] ||
407
361
  !response.choices[0].message) {
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");
362
+ console.error(chalk_1.default.red('Error: Unexpected response format from API'));
363
+ console.error(chalk_1.default.red('Response:', JSON.stringify(response, null, 2)));
364
+ throw new Error('Unexpected response format from API');
411
365
  }
412
366
  // Get assistant's response
413
367
  const assistantMessage = response.choices[0].message.content;
414
368
  // Add to messages array
415
369
  messages.push({
416
- role: "assistant",
417
370
  content: assistantMessage,
371
+ role: 'assistant',
418
372
  });
419
373
  // Display the response
420
- console.log(chalk_1.default.blue("Assistant: "));
374
+ console.log(chalk_1.default.blue('Assistant: '));
421
375
  // Check if the response contains markdown and render it if it does
422
376
  if ((0, markdown_renderer_1.containsMarkdown)(assistantMessage)) {
423
377
  console.log((0, markdown_renderer_1.renderMarkdown)(assistantMessage));
@@ -430,28 +384,28 @@ function registerChatCommands(program) {
430
384
  askQuestion();
431
385
  }
432
386
  catch (error) {
433
- console.error(chalk_1.default.red("Error: Failed to get response"));
387
+ console.error(chalk_1.default.red('Error: Failed to get response'));
434
388
  if (error instanceof Error) {
435
389
  console.error(chalk_1.default.red(error.message));
436
390
  }
437
391
  // Continue despite error
438
392
  askQuestion();
439
393
  }
440
- }));
394
+ });
441
395
  };
442
396
  // Start the conversation
443
397
  askQuestion();
444
398
  }
445
399
  catch (error) {
446
- (0, error_handler_1.handleError)("Failed to create chat completion", error);
400
+ (0, error_handler_1.handleError)('Failed to create chat completion', error);
447
401
  }
448
- }));
402
+ });
449
403
  chat
450
404
  .command(command_structure_1.SUBCOMMANDS.CHAT.LIST)
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")
454
- .action((options) => __awaiter(this, void 0, void 0, function* () {
405
+ .description('List available chat models')
406
+ .option('-k, --api-key <key>', 'API key to use for this request')
407
+ .option('--api-key-id <id>', 'ID of the API key to use from your saved keys')
408
+ .action(async (options) => {
455
409
  try {
456
410
  // If API key ID is provided, fetch the actual key
457
411
  let apiKey = options.apiKey;
@@ -468,59 +422,74 @@ function registerChatCommands(program) {
468
422
  if (apiKeyId && !apiKey) {
469
423
  try {
470
424
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
471
- const keys = yield apiKeyService.list();
472
- const selectedKey = keys.find(key => key.id.toString() === options.apiKeyId);
473
- if (!selectedKey) {
474
- console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
475
- }
476
- else {
425
+ const keys = await apiKeyService.list();
426
+ const selectedKey = keys.find((key) => key.id.toString() === options.apiKeyId);
427
+ if (selectedKey) {
477
428
  console.log(chalk_1.default.dim(`Using API key: ${selectedKey.name}`));
478
429
  // We need to rotate the key to get the actual key value
479
- if (yield confirm(chalk_1.default.yellow(`To use API key "${selectedKey.name}", it needs to be rotated. This will invalidate the current key. Continue? (y/n)`))) {
480
- const rotatedKey = yield apiKeyService.rotate(options.apiKeyId);
430
+ if (await confirm(chalk_1.default.yellow(`To use API key "${selectedKey.name}", it needs to be rotated. This will invalidate the current key. Continue? (y/n)`))) {
431
+ const rotatedKey = await apiKeyService.rotate(options.apiKeyId);
481
432
  apiKey = rotatedKey.key;
482
433
  console.log(chalk_1.default.green(`API key "${selectedKey.name}" rotated successfully.`));
483
434
  }
484
435
  else {
485
- console.log(chalk_1.default.yellow("Using default authentication instead."));
436
+ console.log(chalk_1.default.yellow('Using default authentication instead.'));
486
437
  }
487
438
  }
439
+ else {
440
+ console.log(chalk_1.default.yellow(`API key with ID ${options.apiKeyId} not found. Using default authentication.`));
441
+ }
488
442
  }
489
443
  catch (error) {
490
- console.error(chalk_1.default.red("Error fetching API key:"));
444
+ console.error(chalk_1.default.red('Error fetching API key:'));
491
445
  console.error(error);
492
- console.log(chalk_1.default.yellow("Using default authentication instead."));
446
+ console.log(chalk_1.default.yellow('Using default authentication instead.'));
493
447
  }
494
448
  }
495
449
  const chatService = chat_service_1.ChatService.getInstance();
496
- const models = yield chatService.listModels(apiKey);
450
+ const models = await chatService.listModels(apiKey);
497
451
  // Debug output
498
452
  if (program.opts().debug) {
499
- console.log(chalk_1.default.yellow("DEBUG: Models response:"));
453
+ console.log(chalk_1.default.yellow('DEBUG: Models response:'));
500
454
  console.log(chalk_1.default.yellow(JSON.stringify(models, null, 2)));
501
455
  }
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)));
456
+ console.log(chalk_1.default.bold('Available Chat Models:'));
457
+ console.log(chalk_1.default.dim(''.repeat(70)));
458
+ console.log(chalk_1.default.dim('MODEL ID'.padEnd(40)) + chalk_1.default.dim('CAPABILITIES'));
459
+ console.log(chalk_1.default.dim(''.repeat(70)));
506
460
  // Filter to only show active models
507
461
  const activeModels = models.data.filter((model) => model.active === true);
508
462
  activeModels.forEach((model) => {
509
463
  const capabilities = [];
510
464
  if (model.capabilities.vision)
511
- capabilities.push("vision");
465
+ capabilities.push('vision');
512
466
  if (model.capabilities.function_calling)
513
- capabilities.push("function_calling");
467
+ capabilities.push('function_calling');
514
468
  if (model.capabilities.json_mode)
515
- capabilities.push("json_mode");
469
+ capabilities.push('json_mode');
516
470
  // Format model ID in Huggingface compatible format (owner/model)
517
471
  const modelId = `${model.owned_by.toLowerCase()}/${model.id}`.padEnd(40);
518
- console.log(modelId + capabilities.join(", "));
472
+ console.log(modelId + capabilities.join(', '));
519
473
  });
520
474
  }
521
475
  catch (error) {
522
- (0, error_handler_1.handleError)("Failed to list chat models", error);
476
+ (0, error_handler_1.handleError)('Failed to list chat models', error);
523
477
  }
524
- }));
478
+ });
525
479
  }
526
480
  exports.registerChatCommands = registerChatCommands;
481
+ /**
482
+ * Helper function to get user confirmation
483
+ */
484
+ async function confirm(question) {
485
+ const rl = node_readline_1.default.createInterface({
486
+ input: process.stdin,
487
+ output: process.stdout,
488
+ });
489
+ return new Promise((resolve) => {
490
+ rl.question(question, (answer) => {
491
+ rl.close();
492
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
493
+ });
494
+ });
495
+ }