berget 1.1.0 → 1.3.0

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.
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -19,13 +42,10 @@ var __rest = (this && this.__rest) || function (s, e) {
19
42
  }
20
43
  return t;
21
44
  };
22
- var __importDefault = (this && this.__importDefault) || function (mod) {
23
- return (mod && mod.__esModule) ? mod : { "default": mod };
24
- };
25
45
  Object.defineProperty(exports, "__esModule", { value: true });
26
46
  exports.ChatService = void 0;
27
47
  const client_1 = require("../client");
28
- const chalk_1 = __importDefault(require("chalk"));
48
+ const logger_1 = require("../utils/logger");
29
49
  /**
30
50
  * Service for interacting with the chat API
31
51
  * Command group: chat
@@ -47,57 +67,95 @@ class ChatService {
47
67
  createCompletion(options) {
48
68
  return __awaiter(this, void 0, void 0, function* () {
49
69
  try {
70
+ logger_1.logger.debug('Starting createCompletion method');
71
+ // Initialize options if undefined
72
+ const optionsCopy = options ? Object.assign({}, options) : { messages: [] };
73
+ // Check if messages are defined
74
+ if (!optionsCopy.messages || !Array.isArray(optionsCopy.messages)) {
75
+ logger_1.logger.error('messages is undefined or not an array');
76
+ optionsCopy.messages = [];
77
+ }
78
+ // Log the options object
79
+ logger_1.logger.debug('Starting createCompletion with options:');
80
+ try {
81
+ logger_1.logger.debug(JSON.stringify(Object.assign(Object.assign({}, optionsCopy), { apiKey: optionsCopy.apiKey ? '***' : undefined, messages: optionsCopy.messages
82
+ ? `${optionsCopy.messages.length} messages`
83
+ : '0 messages' }), null, 2));
84
+ }
85
+ catch (error) {
86
+ logger_1.logger.error('Failed to stringify options:', error);
87
+ }
50
88
  const headers = {};
51
- // Check if debug is enabled
52
- const isDebug = process.argv.includes('--debug');
53
- if (isDebug) {
54
- console.log(chalk_1.default.yellow('DEBUG: Chat completion options:'));
55
- console.log(chalk_1.default.yellow(JSON.stringify(options, null, 2)));
89
+ // Check for environment variables first - prioritize this over everything else
90
+ const envApiKey = process.env.BERGET_API_KEY;
91
+ if (envApiKey) {
92
+ logger_1.logger.debug('Using API key from BERGET_API_KEY environment variable');
93
+ optionsCopy.apiKey = envApiKey;
94
+ // Skip the default API key logic if we already have a key
95
+ return this.executeCompletion(optionsCopy, headers);
56
96
  }
57
- // If an API key is provided, use it for this request
58
- if (options.apiKey) {
59
- headers['Authorization'] = `Bearer ${options.apiKey}`;
60
- // Remove apiKey from options before sending to API
61
- const { apiKey } = options, requestOptions = __rest(options, ["apiKey"]);
62
- if (isDebug) {
63
- console.log(chalk_1.default.yellow('DEBUG: Using provided API key'));
64
- console.log(chalk_1.default.yellow('DEBUG: Request options:'));
65
- console.log(chalk_1.default.yellow(JSON.stringify(requestOptions, null, 2)));
66
- }
67
- const { data, error } = yield this.client.POST('/v1/chat/completions', {
68
- body: requestOptions,
69
- headers
70
- });
71
- if (isDebug) {
72
- console.log(chalk_1.default.yellow('DEBUG: API response:'));
73
- console.log(chalk_1.default.yellow(JSON.stringify({ data, error }, null, 2)));
74
- // Output the complete response data for debugging
75
- console.log(chalk_1.default.yellow('DEBUG: Complete response data:'));
76
- console.log(chalk_1.default.yellow(JSON.stringify(data, null, 2)));
77
- }
78
- if (error)
79
- throw new Error(JSON.stringify(error));
80
- return data;
97
+ // If API key is already provided, use it directly
98
+ else if (optionsCopy.apiKey) {
99
+ logger_1.logger.debug('Using API key provided in options');
100
+ // Skip the default API key logic if we already have a key
101
+ return this.executeCompletion(optionsCopy, headers);
81
102
  }
103
+ // Only try to get the default API key if no API key is provided and no env var is set
82
104
  else {
83
- // Use the default authenticated client
84
- if (isDebug) {
85
- console.log(chalk_1.default.yellow('DEBUG: Using default authentication'));
105
+ logger_1.logger.debug('No API key provided, trying to get default');
106
+ try {
107
+ // Import the DefaultApiKeyManager directly
108
+ logger_1.logger.debug('Importing DefaultApiKeyManager');
109
+ const DefaultApiKeyManager = (yield Promise.resolve().then(() => __importStar(require('../utils/default-api-key')))).DefaultApiKeyManager;
110
+ const defaultApiKeyManager = DefaultApiKeyManager.getInstance();
111
+ logger_1.logger.debug('Got DefaultApiKeyManager instance');
112
+ // Try to get the default API key
113
+ logger_1.logger.debug('Calling promptForDefaultApiKey');
114
+ const defaultApiKeyData = defaultApiKeyManager.getDefaultApiKeyData();
115
+ const apiKey = (defaultApiKeyData === null || defaultApiKeyData === void 0 ? void 0 : defaultApiKeyData.key) ||
116
+ (yield defaultApiKeyManager.promptForDefaultApiKey());
117
+ logger_1.logger.debug(`Default API key data exists: ${!!defaultApiKeyData}`);
118
+ logger_1.logger.debug(`promptForDefaultApiKey returned: ${apiKey ? 'a key' : 'null'}`);
119
+ if (apiKey) {
120
+ logger_1.logger.debug('Using API key from default API key manager');
121
+ optionsCopy.apiKey = apiKey;
122
+ }
123
+ else {
124
+ logger_1.logger.warn('No API key available. You need to either:');
125
+ logger_1.logger.warn('1. Create an API key with: berget api-keys create --name "My Key"');
126
+ logger_1.logger.warn('2. Set a default API key with: berget api-keys set-default <id>');
127
+ logger_1.logger.warn('3. Provide an API key with the --api-key option');
128
+ logger_1.logger.warn('4. Set the BERGET_API_KEY environment variable');
129
+ logger_1.logger.warn('\nExample:');
130
+ logger_1.logger.warn(' export BERGET_API_KEY=your_api_key_here');
131
+ logger_1.logger.warn(' # or for a single command:');
132
+ logger_1.logger.warn(' BERGET_API_KEY=your_api_key_here berget chat run google/gemma-3-27b-it');
133
+ throw new Error('No API key provided and no default API key set');
134
+ }
135
+ // Set the API key in the options
136
+ logger_1.logger.debug('Setting API key in options');
137
+ // Only set the API key if it's not null
138
+ if (apiKey) {
139
+ optionsCopy.apiKey = apiKey;
140
+ }
86
141
  }
87
- const { data, error } = yield this.client.POST('/v1/chat/completions', {
88
- body: options
89
- });
90
- if (isDebug) {
91
- console.log(chalk_1.default.yellow('DEBUG: API response:'));
92
- console.log(chalk_1.default.yellow(JSON.stringify({ data, error }, null, 2)));
93
- // Output the complete response data for debugging
94
- console.log(chalk_1.default.yellow('DEBUG: Complete response data:'));
95
- console.log(chalk_1.default.yellow(JSON.stringify(data, null, 2)));
142
+ catch (error) {
143
+ logger_1.logger.error('Error getting API key:');
144
+ if (error instanceof Error) {
145
+ logger_1.logger.error(error.message);
146
+ }
147
+ logger_1.logger.warn('Please create an API key with: berget api-keys create --name "My Key"');
148
+ throw new Error('Failed to get API key');
96
149
  }
97
- if (error)
98
- throw new Error(JSON.stringify(error));
99
- return data;
100
150
  }
151
+ // Set default model if not provided
152
+ if (!optionsCopy.model) {
153
+ logger_1.logger.debug('No model specified, using default: google/gemma-3-27b-it');
154
+ optionsCopy.model = 'google/gemma-3-27b-it';
155
+ }
156
+ logger_1.logger.debug('Chat completion options:');
157
+ logger_1.logger.debug(JSON.stringify(Object.assign(Object.assign({}, optionsCopy), { apiKey: optionsCopy.apiKey ? '***' : undefined }), null, 2));
158
+ return this.executeCompletion(optionsCopy, headers);
101
159
  }
102
160
  catch (error) {
103
161
  // Improved error handling
@@ -115,11 +173,178 @@ class ChatService {
115
173
  errorMessage = `Chat error: ${error.message}`;
116
174
  }
117
175
  }
118
- console.error(chalk_1.default.red(errorMessage));
176
+ logger_1.logger.error(errorMessage);
119
177
  throw new Error(errorMessage);
120
178
  }
121
179
  });
122
180
  }
181
+ /**
182
+ * Execute the completion request with the provided options
183
+ * @param options The completion options
184
+ * @param headers Additional headers to include
185
+ * @returns The completion response
186
+ */
187
+ executeCompletion(options, headers = {}) {
188
+ return __awaiter(this, void 0, void 0, function* () {
189
+ try {
190
+ // If an API key is provided, use it for this request
191
+ if (options.apiKey) {
192
+ // API keys should be sent directly, not with Bearer prefix
193
+ headers['Authorization'] = options.apiKey;
194
+ }
195
+ // Remove apiKey and onChunk from options before sending to API
196
+ const { apiKey, onChunk } = options, requestOptions = __rest(options, ["apiKey", "onChunk"]);
197
+ logger_1.logger.debug('Request options:');
198
+ logger_1.logger.debug(JSON.stringify(Object.assign(Object.assign({}, requestOptions), { messages: requestOptions.messages
199
+ ? `${requestOptions.messages.length} messages`
200
+ : '0 messages' }), null, 2));
201
+ // Handle streaming responses differently
202
+ if (requestOptions.stream && onChunk) {
203
+ return yield this.handleStreamingResponse(Object.assign(Object.assign({}, requestOptions), { onChunk }), headers);
204
+ }
205
+ else {
206
+ // Ensure model is always defined for the API call
207
+ const requestBody = Object.assign(Object.assign({}, requestOptions), { model: requestOptions.model || 'google/gemma-3-27b-it' });
208
+ // Debug the headers being sent
209
+ logger_1.logger.debug('Headers being sent:');
210
+ logger_1.logger.debug(JSON.stringify(headers, null, 2));
211
+ const response = yield this.client.POST('/v1/chat/completions', {
212
+ body: requestBody,
213
+ headers,
214
+ });
215
+ // Check if response has an error property
216
+ const responseAny = response;
217
+ if (responseAny && responseAny.error)
218
+ throw new Error(JSON.stringify(responseAny.error));
219
+ logger_1.logger.debug('API response:');
220
+ logger_1.logger.debug(JSON.stringify(response, null, 2));
221
+ // Output the complete response data for debugging
222
+ logger_1.logger.debug('Complete response data:');
223
+ logger_1.logger.debug(JSON.stringify(response.data, null, 2));
224
+ return response.data;
225
+ }
226
+ }
227
+ catch (requestError) {
228
+ logger_1.logger.debug(`Request error: ${requestError instanceof Error
229
+ ? requestError.message
230
+ : String(requestError)}`);
231
+ throw requestError;
232
+ }
233
+ });
234
+ }
235
+ /**
236
+ * Handle the case when no API key is available
237
+ */
238
+ handleNoApiKey() {
239
+ // We've exhausted all options for getting an API key
240
+ logger_1.logger.warn('No API key available. You need to either:');
241
+ logger_1.logger.warn('1. Create an API key with: berget api-keys create --name "My Key"');
242
+ logger_1.logger.warn('2. Set a default API key with: berget api-keys set-default <id>');
243
+ logger_1.logger.warn('3. Provide an API key with the --api-key option');
244
+ logger_1.logger.warn('4. Set the BERGET_API_KEY environment variable');
245
+ logger_1.logger.warn('\nExample:');
246
+ logger_1.logger.warn(' export BERGET_API_KEY=your_api_key_here');
247
+ logger_1.logger.warn(' # or for a single command:');
248
+ logger_1.logger.warn(' BERGET_API_KEY=your_api_key_here berget chat run google/gemma-3-27b-it');
249
+ throw new Error('No API key available. Please provide an API key or set a default API key.');
250
+ }
251
+ /**
252
+ * Handle streaming response from the API
253
+ * @param options Request options
254
+ * @param headers Request headers
255
+ * @returns A promise that resolves when the stream is complete
256
+ */
257
+ handleStreamingResponse(options, headers) {
258
+ return __awaiter(this, void 0, void 0, function* () {
259
+ logger_1.logger.debug('Handling streaming response');
260
+ // Create URL with query parameters
261
+ const url = new URL(`${client_1.API_BASE_URL}/v1/chat/completions`);
262
+ // Debug the headers and options
263
+ logger_1.logger.debug('Streaming headers:');
264
+ logger_1.logger.debug(JSON.stringify(headers, null, 2));
265
+ logger_1.logger.debug('Streaming options:');
266
+ logger_1.logger.debug(JSON.stringify(Object.assign(Object.assign({}, options), { onChunk: options.onChunk ? 'function present' : 'no function' }), null, 2));
267
+ try {
268
+ // Make fetch request directly to handle streaming
269
+ const response = yield fetch(url.toString(), {
270
+ method: 'POST',
271
+ headers: Object.assign({ 'Content-Type': 'application/json', Accept: 'text/event-stream' }, headers),
272
+ body: JSON.stringify(options),
273
+ });
274
+ if (!response.ok) {
275
+ const errorText = yield response.text();
276
+ logger_1.logger.error(`Stream request failed: ${response.status} ${response.statusText}`);
277
+ logger_1.logger.debug(`Error response: ${errorText}`);
278
+ throw new Error(`Stream request failed: ${response.status} ${response.statusText}`);
279
+ }
280
+ if (!response.body) {
281
+ throw new Error('No response body received');
282
+ }
283
+ // Process the stream
284
+ const reader = response.body.getReader();
285
+ const decoder = new TextDecoder();
286
+ let fullContent = '';
287
+ let fullResponse = null;
288
+ while (true) {
289
+ const { done, value } = yield reader.read();
290
+ if (done)
291
+ break;
292
+ const chunk = decoder.decode(value, { stream: true });
293
+ logger_1.logger.debug(`Received chunk: ${chunk.length} bytes`);
294
+ // Process the chunk - it may contain multiple SSE events
295
+ const lines = chunk.split('\n');
296
+ for (const line of lines) {
297
+ if (line.startsWith('data:')) {
298
+ const jsonData = line.slice(5).trim();
299
+ // Skip empty data or [DONE] marker
300
+ if (jsonData === '' || jsonData === '[DONE]')
301
+ continue;
302
+ try {
303
+ const parsedData = JSON.parse(jsonData);
304
+ // Call the onChunk callback with the parsed data
305
+ if (options.onChunk) {
306
+ options.onChunk(parsedData);
307
+ }
308
+ // Keep track of the full response
309
+ if (!fullResponse) {
310
+ fullResponse = parsedData;
311
+ }
312
+ else if (parsedData.choices &&
313
+ parsedData.choices[0] &&
314
+ parsedData.choices[0].delta) {
315
+ // Accumulate content for the full response
316
+ if (parsedData.choices[0].delta.content) {
317
+ fullContent += parsedData.choices[0].delta.content;
318
+ }
319
+ }
320
+ }
321
+ catch (e) {
322
+ logger_1.logger.error(`Error parsing chunk: ${e}`);
323
+ logger_1.logger.debug(`Problematic chunk: ${jsonData}`);
324
+ }
325
+ }
326
+ }
327
+ }
328
+ // Construct the final response object similar to non-streaming response
329
+ if (fullResponse) {
330
+ if (fullContent) {
331
+ fullResponse.choices[0].message = {
332
+ role: 'assistant',
333
+ content: fullContent,
334
+ };
335
+ }
336
+ return fullResponse;
337
+ }
338
+ return {
339
+ choices: [{ message: { role: 'assistant', content: fullContent } }],
340
+ };
341
+ }
342
+ catch (error) {
343
+ logger_1.logger.error(`Streaming error: ${error instanceof Error ? error.message : String(error)}`);
344
+ throw error;
345
+ }
346
+ });
347
+ }
123
348
  /**
124
349
  * List available models
125
350
  * Command: berget chat list
@@ -127,9 +352,12 @@ class ChatService {
127
352
  listModels(apiKey) {
128
353
  return __awaiter(this, void 0, void 0, function* () {
129
354
  try {
130
- if (apiKey) {
355
+ // Check for environment variable first, then fallback to provided API key
356
+ const envApiKey = process.env.BERGET_API_KEY;
357
+ const effectiveApiKey = envApiKey || apiKey;
358
+ if (effectiveApiKey) {
131
359
  const headers = {
132
- 'Authorization': `Bearer ${apiKey}`
360
+ Authorization: effectiveApiKey,
133
361
  };
134
362
  const { data, error } = yield this.client.GET('/v1/models', { headers });
135
363
  if (error)
@@ -151,9 +379,9 @@ class ChatService {
151
379
  // Try to parse the error message as JSON
152
380
  const parsedError = JSON.parse(error.message);
153
381
  if (parsedError.error) {
154
- errorMessage = `Models error: ${typeof parsedError.error === 'string' ?
155
- parsedError.error :
156
- (parsedError.error.message || JSON.stringify(parsedError.error))}`;
382
+ errorMessage = `Models error: ${typeof parsedError.error === 'string'
383
+ ? parsedError.error
384
+ : parsedError.error.message || JSON.stringify(parsedError.error)}`;
157
385
  }
158
386
  }
159
387
  catch (e) {
@@ -161,7 +389,7 @@ class ChatService {
161
389
  errorMessage = `Models error: ${error.message}`;
162
390
  }
163
391
  }
164
- console.error(chalk_1.default.red(errorMessage));
392
+ logger_1.logger.error(errorMessage);
165
393
  throw new Error(errorMessage);
166
394
  }
167
395
  });
@@ -173,5 +401,5 @@ ChatService.COMMAND_GROUP = 'chat';
173
401
  // Subcommands for this service
174
402
  ChatService.COMMANDS = {
175
403
  RUN: 'run',
176
- LIST: 'list'
404
+ LIST: 'list',
177
405
  };
@@ -22,6 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
25
34
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
36
  };
@@ -30,7 +39,9 @@ exports.DefaultApiKeyManager = void 0;
30
39
  const fs = __importStar(require("fs"));
31
40
  const path = __importStar(require("path"));
32
41
  const os = __importStar(require("os"));
33
- const chalk_1 = __importDefault(require("chalk"));
42
+ const api_key_service_1 = require("../services/api-key-service");
43
+ const readline_1 = __importDefault(require("readline"));
44
+ const logger_1 = require("./logger");
34
45
  /**
35
46
  * Manages the default API key for chat commands
36
47
  */
@@ -62,7 +73,7 @@ class DefaultApiKeyManager {
62
73
  }
63
74
  }
64
75
  catch (error) {
65
- console.error(chalk_1.default.dim('Failed to load default API key configuration'));
76
+ logger_1.logger.debug('Failed to load default API key configuration');
66
77
  this.defaultApiKey = null;
67
78
  }
68
79
  }
@@ -84,20 +95,27 @@ class DefaultApiKeyManager {
84
95
  }
85
96
  }
86
97
  catch (error) {
87
- console.error(chalk_1.default.dim('Failed to save default API key configuration'));
98
+ logger_1.logger.debug('Failed to save default API key configuration');
88
99
  }
89
100
  }
90
101
  /**
91
102
  * Set the default API key
92
103
  */
93
- setDefaultApiKey(id, name, prefix) {
94
- this.defaultApiKey = { id, name, prefix };
104
+ setDefaultApiKey(id, name, prefix, key) {
105
+ this.defaultApiKey = { id, name, prefix, key };
95
106
  this.saveConfig();
96
107
  }
97
108
  /**
98
- * Get the default API key
109
+ * Get the default API key string
99
110
  */
100
111
  getDefaultApiKey() {
112
+ var _a;
113
+ return ((_a = this.defaultApiKey) === null || _a === void 0 ? void 0 : _a.key) || null;
114
+ }
115
+ /**
116
+ * Get the default API key data object
117
+ */
118
+ getDefaultApiKeyData() {
101
119
  return this.defaultApiKey;
102
120
  }
103
121
  /**
@@ -107,5 +125,96 @@ class DefaultApiKeyManager {
107
125
  this.defaultApiKey = null;
108
126
  this.saveConfig();
109
127
  }
128
+ /**
129
+ * Prompts the user to select a default API key if none is set
130
+ * @returns The selected API key or null if none was selected
131
+ */
132
+ promptForDefaultApiKey() {
133
+ return __awaiter(this, void 0, void 0, function* () {
134
+ try {
135
+ logger_1.logger.debug('promptForDefaultApiKey called');
136
+ // If we already have a default API key, return it
137
+ if (this.defaultApiKey) {
138
+ logger_1.logger.debug('Using existing default API key');
139
+ return this.defaultApiKey.key;
140
+ }
141
+ logger_1.logger.debug('No default API key found, getting ApiKeyService');
142
+ const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
143
+ // Get all API keys
144
+ let apiKeys;
145
+ try {
146
+ logger_1.logger.debug('Calling apiKeyService.list()');
147
+ apiKeys = yield apiKeyService.list();
148
+ logger_1.logger.debug(`Got ${apiKeys ? apiKeys.length : 0} API keys`);
149
+ if (!apiKeys || apiKeys.length === 0) {
150
+ logger_1.logger.warn('No API keys found. Create one with:');
151
+ logger_1.logger.info(' berget api-keys create --name "My Key"');
152
+ return null;
153
+ }
154
+ }
155
+ catch (error) {
156
+ // Check if this is an authentication error
157
+ const errorMessage = error instanceof Error ? error.message : String(error);
158
+ const isAuthError = errorMessage.includes('Unauthorized') ||
159
+ errorMessage.includes('Authentication failed') ||
160
+ errorMessage.includes('AUTH_FAILED');
161
+ if (isAuthError) {
162
+ logger_1.logger.warn('Authentication required. Please run `berget auth login` first.');
163
+ }
164
+ else {
165
+ logger_1.logger.error('Error fetching API keys:');
166
+ if (error instanceof Error) {
167
+ logger_1.logger.error(error.message);
168
+ logger_1.logger.debug(`API key list error: ${error.message}`);
169
+ logger_1.logger.debug(`Stack: ${error.stack}`);
170
+ }
171
+ }
172
+ return null;
173
+ }
174
+ logger_1.logger.info('Select an API key to use as default:');
175
+ // Display available API keys
176
+ apiKeys.forEach((key, index) => {
177
+ logger_1.logger.log(` ${index + 1}. ${key.name} (${key.prefix}...)`);
178
+ });
179
+ // Create readline interface for user input
180
+ const rl = readline_1.default.createInterface({
181
+ input: process.stdin,
182
+ output: process.stdout
183
+ });
184
+ // Prompt for selection
185
+ const selection = yield new Promise((resolve) => {
186
+ rl.question('Enter number (or press Enter to cancel): ', (answer) => {
187
+ rl.close();
188
+ const num = parseInt(answer.trim(), 10);
189
+ if (isNaN(num) || num < 1 || num > apiKeys.length) {
190
+ resolve(-1); // Invalid selection
191
+ }
192
+ else {
193
+ resolve(num - 1); // Convert to zero-based index
194
+ }
195
+ });
196
+ });
197
+ if (selection === -1) {
198
+ logger_1.logger.warn('No API key selected');
199
+ return null;
200
+ }
201
+ const selectedKey = apiKeys[selection];
202
+ // Create a new API key with the selected name
203
+ const newKey = yield apiKeyService.create({
204
+ name: `CLI Default (copy of ${selectedKey.name})`,
205
+ description: 'Created automatically by the Berget CLI for default use'
206
+ });
207
+ // Save the new key as default
208
+ this.setDefaultApiKey(newKey.id.toString(), newKey.name, newKey.key.substring(0, 8), // Use first 8 chars as prefix
209
+ newKey.key);
210
+ logger_1.logger.success(`✓ Default API key set to: ${newKey.name}`);
211
+ return newKey.key;
212
+ }
213
+ catch (error) {
214
+ logger_1.logger.error('Failed to set default API key:', error);
215
+ return null;
216
+ }
217
+ });
218
+ }
110
219
  }
111
220
  exports.DefaultApiKeyManager = DefaultApiKeyManager;
@@ -35,11 +35,11 @@ function handleError(message, error) {
35
35
  console.error(chalk_1.default.dim(`Details: ${error.message}`));
36
36
  }
37
37
  // Check for authentication errors
38
- if ((typeof error === 'string' && error.includes('Unauthorized')) ||
39
- (error && error.message && error.message.includes('Unauthorized')) ||
40
- (error && error.code && error.code === 401)) {
38
+ if ((typeof error === 'string' && (error.includes('Unauthorized') || error.includes('Authentication failed'))) ||
39
+ (error && error.message && (error.message.includes('Unauthorized') || error.message.includes('Authentication failed'))) ||
40
+ (error && error.code && (error.code === 401 || error.code === 'AUTH_FAILED'))) {
41
41
  console.error(chalk_1.default.yellow('\nYou need to be logged in to use this command.'));
42
- console.error(chalk_1.default.yellow('Run `berget login` to authenticate.'));
42
+ console.error(chalk_1.default.yellow('Run `berget auth login` to authenticate.'));
43
43
  }
44
44
  }
45
45
  exports.handleError = handleError;