berget 2.2.6 → 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 (145) hide show
  1. package/.github/workflows/publish.yml +2 -2
  2. package/.github/workflows/test.yml +10 -4
  3. package/.husky/pre-commit +1 -0
  4. package/.prettierignore +15 -0
  5. package/.prettierrc +7 -3
  6. package/CONTRIBUTING.md +38 -0
  7. package/README.md +2 -148
  8. package/dist/index.js +10 -11
  9. package/dist/package.json +30 -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 +97 -117
  20. package/dist/src/commands/api-keys.js +75 -90
  21. package/dist/src/commands/auth.js +7 -16
  22. package/dist/src/commands/autocomplete.js +1 -1
  23. package/dist/src/commands/billing.js +6 -17
  24. package/dist/src/commands/chat.js +68 -101
  25. package/dist/src/commands/clusters.js +9 -18
  26. package/dist/src/commands/code/__tests__/auth-sync.test.js +351 -0
  27. package/dist/src/commands/code/__tests__/fake-api-key-service.js +13 -0
  28. package/dist/src/commands/code/__tests__/fake-auth-service.js +47 -0
  29. package/dist/src/commands/code/__tests__/fake-command-runner.js +21 -34
  30. package/dist/src/commands/code/__tests__/fake-file-store.js +20 -33
  31. package/dist/src/commands/code/__tests__/fake-prompter.js +83 -57
  32. package/dist/src/commands/code/__tests__/setup-flow.test.js +359 -92
  33. package/dist/src/commands/code/adapters/clack-prompter.js +15 -22
  34. package/dist/src/commands/code/adapters/fs-file-store.js +26 -40
  35. package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -37
  36. package/dist/src/commands/code/auth-sync.js +270 -0
  37. package/dist/src/commands/code/errors.js +12 -9
  38. package/dist/src/commands/code/ports/auth-services.js +2 -0
  39. package/dist/src/commands/code/setup.js +387 -281
  40. package/dist/src/commands/code.js +205 -332
  41. package/dist/src/commands/index.js +5 -5
  42. package/dist/src/commands/models.js +6 -17
  43. package/dist/src/commands/users.js +5 -16
  44. package/dist/src/constants/command-structure.js +104 -104
  45. package/dist/src/services/api-key-service.js +132 -157
  46. package/dist/src/services/auth-service.js +89 -342
  47. package/dist/src/services/browser-auth.js +268 -0
  48. package/dist/src/services/chat-service.js +371 -401
  49. package/dist/src/services/cluster-service.js +47 -62
  50. package/dist/src/services/collaborator-service.js +10 -25
  51. package/dist/src/services/flux-service.js +14 -29
  52. package/dist/src/services/helm-service.js +10 -25
  53. package/dist/src/services/kubectl-service.js +16 -33
  54. package/dist/src/utils/config-checker.js +3 -3
  55. package/dist/src/utils/config-loader.js +95 -95
  56. package/dist/src/utils/default-api-key.js +124 -134
  57. package/dist/src/utils/env-manager.js +55 -66
  58. package/dist/src/utils/error-handler.js +20 -21
  59. package/dist/src/utils/logger.js +72 -65
  60. package/dist/src/utils/markdown-renderer.js +27 -27
  61. package/dist/src/utils/opencode-validator.js +63 -68
  62. package/dist/src/utils/token-manager.js +74 -45
  63. package/dist/tests/commands/chat.test.js +16 -25
  64. package/dist/tests/commands/code.test.js +95 -104
  65. package/dist/tests/utils/config-loader.test.js +48 -48
  66. package/dist/tests/utils/env-manager.test.js +43 -52
  67. package/dist/tests/utils/opencode-validator.test.js +22 -21
  68. package/dist/vitest.config.js +1 -1
  69. package/eslint.config.mjs +67 -0
  70. package/index.ts +35 -42
  71. package/package.json +30 -2
  72. package/src/agents/app.ts +27 -0
  73. package/src/agents/backend.ts +24 -0
  74. package/src/agents/devops.ts +33 -0
  75. package/src/agents/frontend.ts +24 -0
  76. package/src/agents/fullstack.ts +24 -0
  77. package/src/agents/index.ts +73 -0
  78. package/src/agents/quality.ts +69 -0
  79. package/src/agents/security.ts +26 -0
  80. package/src/agents/types.ts +17 -0
  81. package/src/client.ts +118 -152
  82. package/src/commands/api-keys.ts +241 -333
  83. package/src/commands/auth.ts +22 -27
  84. package/src/commands/autocomplete.ts +9 -9
  85. package/src/commands/billing.ts +20 -24
  86. package/src/commands/chat.ts +248 -338
  87. package/src/commands/clusters.ts +27 -26
  88. package/src/commands/code/__tests__/auth-sync.test.ts +482 -0
  89. package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
  90. package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
  91. package/src/commands/code/__tests__/fake-command-runner.ts +45 -42
  92. package/src/commands/code/__tests__/fake-file-store.ts +32 -23
  93. package/src/commands/code/__tests__/fake-prompter.ts +116 -77
  94. package/src/commands/code/__tests__/setup-flow.test.ts +624 -268
  95. package/src/commands/code/adapters/clack-prompter.ts +53 -39
  96. package/src/commands/code/adapters/fs-file-store.ts +32 -27
  97. package/src/commands/code/adapters/spawn-command-runner.ts +38 -29
  98. package/src/commands/code/auth-sync.ts +329 -0
  99. package/src/commands/code/errors.ts +18 -18
  100. package/src/commands/code/ports/auth-services.ts +14 -0
  101. package/src/commands/code/ports/command-runner.ts +8 -4
  102. package/src/commands/code/ports/file-store.ts +5 -4
  103. package/src/commands/code/ports/prompter.ts +24 -18
  104. package/src/commands/code/setup.ts +570 -340
  105. package/src/commands/code.ts +338 -539
  106. package/src/commands/index.ts +20 -19
  107. package/src/commands/models.ts +28 -32
  108. package/src/commands/users.ts +15 -21
  109. package/src/constants/command-structure.ts +134 -157
  110. package/src/services/api-key-service.ts +105 -122
  111. package/src/services/auth-service.ts +99 -345
  112. package/src/services/browser-auth.ts +296 -0
  113. package/src/services/chat-service.ts +265 -299
  114. package/src/services/cluster-service.ts +42 -45
  115. package/src/services/collaborator-service.ts +14 -19
  116. package/src/services/flux-service.ts +23 -25
  117. package/src/services/helm-service.ts +19 -21
  118. package/src/services/kubectl-service.ts +17 -19
  119. package/src/types/api.d.ts +1905 -1907
  120. package/src/types/json.d.ts +2 -2
  121. package/src/utils/config-checker.ts +10 -10
  122. package/src/utils/config-loader.ts +162 -178
  123. package/src/utils/default-api-key.ts +114 -125
  124. package/src/utils/env-manager.ts +53 -57
  125. package/src/utils/error-handler.ts +61 -56
  126. package/src/utils/logger.ts +79 -73
  127. package/src/utils/markdown-renderer.ts +31 -31
  128. package/src/utils/opencode-validator.ts +85 -89
  129. package/src/utils/token-manager.ts +108 -87
  130. package/templates/agents/app.md +1 -0
  131. package/templates/agents/backend.md +1 -0
  132. package/templates/agents/devops.md +2 -0
  133. package/templates/agents/frontend.md +1 -0
  134. package/templates/agents/fullstack.md +1 -0
  135. package/templates/agents/quality.md +45 -40
  136. package/templates/agents/security.md +1 -0
  137. package/tests/commands/chat.test.ts +53 -62
  138. package/tests/commands/code.test.ts +265 -310
  139. package/tests/utils/config-loader.test.ts +189 -188
  140. package/tests/utils/env-manager.test.ts +110 -113
  141. package/tests/utils/opencode-validator.test.ts +52 -56
  142. package/tsconfig.json +4 -3
  143. package/vitest.config.ts +3 -3
  144. package/AGENTS.md +0 -374
  145. package/TODO.md +0 -19
@@ -23,63 +23,49 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.getProviderModels = exports.getModelConfig = exports.getAllAgentConfigs = exports.getAgentConfig = exports.getConfigLoader = exports.ConfigLoader = void 0;
27
- const fs = __importStar(require("fs"));
28
- const path = __importStar(require("path"));
26
+ exports.getProviderModels = exports.getModelConfig = exports.getConfigLoader = exports.getAllAgentConfigs = exports.getAgentConfig = exports.ConfigLoader = void 0;
27
+ const fs = __importStar(require("node:fs"));
28
+ const path = __importStar(require("node:path"));
29
29
  const logger_1 = require("./logger");
30
30
  class ConfigLoader {
31
+ static instance;
32
+ config = null;
33
+ configPath;
31
34
  constructor(configPath) {
32
- this.config = null;
33
35
  // Default to opencode.json in current working directory
34
36
  this.configPath = configPath || path.join(process.cwd(), 'opencode.json');
35
37
  }
36
- static getInstance(configPath) {
37
- if (!ConfigLoader.instance) {
38
- ConfigLoader.instance = new ConfigLoader(configPath);
39
- }
40
- return ConfigLoader.instance;
41
- }
42
38
  /**
43
39
  * Clear the singleton instance (for testing purposes)
44
40
  */
45
41
  static clearInstance() {
46
42
  ConfigLoader.instance = null;
47
43
  }
48
- /**
49
- * Load configuration from opencode.json
50
- */
51
- loadConfig() {
52
- if (this.config) {
53
- return this.config;
54
- }
55
- try {
56
- if (!fs.existsSync(this.configPath)) {
57
- throw new Error(`Configuration file not found: ${this.configPath}`);
58
- }
59
- const configContent = fs.readFileSync(this.configPath, 'utf8');
60
- this.config = JSON.parse(configContent);
61
- logger_1.logger.debug(`Loaded configuration from ${this.configPath}`);
62
- return this.config;
63
- }
64
- catch (error) {
65
- logger_1.logger.error(`Failed to load configuration from ${this.configPath}:`, error);
66
- throw new Error(`Failed to load configuration: ${error instanceof Error ? error.message : String(error)}`);
44
+ static getInstance(configPath) {
45
+ if (!ConfigLoader.instance) {
46
+ ConfigLoader.instance = new ConfigLoader(configPath);
67
47
  }
48
+ return ConfigLoader.instance;
68
49
  }
69
50
  /**
70
51
  * Get agent configuration by name
71
52
  */
72
53
  getAgentConfig(agentName) {
73
- var _a;
74
54
  try {
75
55
  const config = this.loadConfig();
76
- return ((_a = config.agent) === null || _a === void 0 ? void 0 : _a[agentName]) || null;
56
+ return config.agent?.[agentName] || null;
77
57
  }
78
- catch (error) {
58
+ catch {
79
59
  // Config file doesn't exist, return null
80
60
  return null;
81
61
  }
82
62
  }
63
+ /**
64
+ * Get list of all available agent names
65
+ */
66
+ getAgentNames() {
67
+ return Object.keys(this.getAllAgentConfigs());
68
+ }
83
69
  /**
84
70
  * Get all agent configurations
85
71
  */
@@ -88,11 +74,30 @@ class ConfigLoader {
88
74
  const config = this.loadConfig();
89
75
  return config.agent || {};
90
76
  }
91
- catch (error) {
77
+ catch {
92
78
  // Config file doesn't exist, return empty object
93
79
  return {};
94
80
  }
95
81
  }
82
+ /**
83
+ * Get command configurations
84
+ */
85
+ getCommandConfigs() {
86
+ try {
87
+ const config = this.loadConfig();
88
+ return config.command || {};
89
+ }
90
+ catch {
91
+ // Config file doesn't exist, return empty object
92
+ return {};
93
+ }
94
+ }
95
+ /**
96
+ * Get the current configuration path
97
+ */
98
+ getConfigPath() {
99
+ return this.configPath;
100
+ }
96
101
  /**
97
102
  * Get model configuration
98
103
  */
@@ -104,7 +109,7 @@ class ConfigLoader {
104
109
  const small = config.small_model || 'berget/gpt-oss';
105
110
  return { primary, small };
106
111
  }
107
- catch (error) {
112
+ catch {
108
113
  // Fallback to defaults when no config exists (init scenario)
109
114
  return {
110
115
  primary: 'berget/glm-4.7',
@@ -112,53 +117,66 @@ class ConfigLoader {
112
117
  };
113
118
  }
114
119
  }
120
+ /**
121
+ * Get list of primary agents (mode: 'primary')
122
+ */
123
+ getPrimaryAgentNames() {
124
+ const agents = this.getAllAgentConfigs();
125
+ return Object.keys(agents).filter((name) => agents[name].mode === 'primary');
126
+ }
127
+ /**
128
+ * Get provider configuration
129
+ */
130
+ getProviderConfig() {
131
+ try {
132
+ const config = this.loadConfig();
133
+ return config.provider || {};
134
+ }
135
+ catch {
136
+ // Config file doesn't exist, return empty object
137
+ return {};
138
+ }
139
+ }
115
140
  /**
116
141
  * Get provider model configuration
117
142
  */
118
143
  getProviderModels() {
119
- var _a, _b;
120
144
  try {
121
145
  const config = this.loadConfig();
122
146
  // Extract from provider configuration
123
- if ((_b = (_a = config.provider) === null || _a === void 0 ? void 0 : _a.berget) === null || _b === void 0 ? void 0 : _b.models) {
147
+ if (config.provider?.berget?.models) {
124
148
  return config.provider.berget.models;
125
149
  }
126
150
  }
127
- catch (error) {
151
+ catch {
128
152
  // Config file doesn't exist, use fallback defaults
129
153
  }
130
154
  // Fallback to defaults
131
155
  return {
132
156
  'glm-4.7': {
157
+ limit: { context: 90000, output: 4000 },
133
158
  name: 'GLM-4.7',
134
- limit: { output: 4000, context: 90000 },
135
159
  },
136
160
  'gpt-oss': {
137
- name: 'GPT-OSS',
138
- limit: { output: 4000, context: 128000 },
161
+ limit: { context: 128000, output: 4000 },
139
162
  modalities: {
140
163
  input: ['text', 'image'],
141
164
  output: ['text'],
142
165
  },
166
+ name: 'GPT-OSS',
143
167
  },
144
168
  'llama-8b': {
169
+ limit: { context: 128000, output: 4000 },
145
170
  name: 'llama-3.1-8b',
146
- limit: { output: 4000, context: 128000 },
147
171
  },
148
172
  };
149
173
  }
150
174
  /**
151
- * Get command configurations
175
+ * Get list of subagents (mode: 'subagent')
152
176
  */
153
- getCommandConfigs() {
154
- try {
155
- const config = this.loadConfig();
156
- return config.command || {};
157
- }
158
- catch (error) {
159
- // Config file doesn't exist, return empty object
160
- return {};
161
- }
177
+ getSubagentNames() {
178
+ const agents = this.getAllAgentConfigs();
179
+ return Object.keys(agents).filter((name) => agents[name].mode === 'subagent');
162
180
  }
163
181
  /**
164
182
  * Get watcher configuration
@@ -170,24 +188,11 @@ class ConfigLoader {
170
188
  ignore: ['node_modules', 'dist', '.git', 'coverage'],
171
189
  });
172
190
  }
173
- catch (error) {
191
+ catch {
174
192
  // Config file doesn't exist, return default watcher config
175
193
  return { ignore: ['node_modules', 'dist', '.git', 'coverage'] };
176
194
  }
177
195
  }
178
- /**
179
- * Get provider configuration
180
- */
181
- getProviderConfig() {
182
- try {
183
- const config = this.loadConfig();
184
- return config.provider || {};
185
- }
186
- catch (error) {
187
- // Config file doesn't exist, return empty object
188
- return {};
189
- }
190
- }
191
196
  /**
192
197
  * Check if an agent exists
193
198
  */
@@ -195,24 +200,25 @@ class ConfigLoader {
195
200
  return agentName in this.getAllAgentConfigs();
196
201
  }
197
202
  /**
198
- * Get list of all available agent names
199
- */
200
- getAgentNames() {
201
- return Object.keys(this.getAllAgentConfigs());
202
- }
203
- /**
204
- * Get list of primary agents (mode: 'primary')
205
- */
206
- getPrimaryAgentNames() {
207
- const agents = this.getAllAgentConfigs();
208
- return Object.keys(agents).filter((name) => agents[name].mode === 'primary');
209
- }
210
- /**
211
- * Get list of subagents (mode: 'subagent')
203
+ * Load configuration from opencode.json
212
204
  */
213
- getSubagentNames() {
214
- const agents = this.getAllAgentConfigs();
215
- return Object.keys(agents).filter((name) => agents[name].mode === 'subagent');
205
+ loadConfig() {
206
+ if (this.config) {
207
+ return this.config;
208
+ }
209
+ try {
210
+ if (!fs.existsSync(this.configPath)) {
211
+ throw new Error(`Configuration file not found: ${this.configPath}`);
212
+ }
213
+ const configContent = fs.readFileSync(this.configPath, 'utf8');
214
+ this.config = JSON.parse(configContent);
215
+ logger_1.logger.debug(`Loaded configuration from ${this.configPath}`);
216
+ return this.config;
217
+ }
218
+ catch (error) {
219
+ logger_1.logger.error(`Failed to load configuration from ${this.configPath}:`, error);
220
+ throw new Error(`Failed to load configuration: ${error instanceof Error ? error.message : String(error)}`);
221
+ }
216
222
  }
217
223
  /**
218
224
  * Reload configuration from file
@@ -228,21 +234,8 @@ class ConfigLoader {
228
234
  this.configPath = configPath;
229
235
  this.config = null; // Force reload
230
236
  }
231
- /**
232
- * Get the current configuration path
233
- */
234
- getConfigPath() {
235
- return this.configPath;
236
- }
237
237
  }
238
238
  exports.ConfigLoader = ConfigLoader;
239
- /**
240
- * Convenience function to get the config loader instance
241
- */
242
- function getConfigLoader(configPath) {
243
- return ConfigLoader.getInstance(configPath);
244
- }
245
- exports.getConfigLoader = getConfigLoader;
246
239
  /**
247
240
  * Convenience function to get agent configuration
248
241
  */
@@ -257,6 +250,13 @@ function getAllAgentConfigs(configPath) {
257
250
  return getConfigLoader(configPath).getAllAgentConfigs();
258
251
  }
259
252
  exports.getAllAgentConfigs = getAllAgentConfigs;
253
+ /**
254
+ * Convenience function to get the config loader instance
255
+ */
256
+ function getConfigLoader(configPath) {
257
+ return ConfigLoader.getInstance(configPath);
258
+ }
259
+ exports.getConfigLoader = getConfigLoader;
260
260
  /**
261
261
  * Convenience function to get model configuration
262
262
  */
@@ -22,32 +22,25 @@ 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
- };
34
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
35
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
27
  };
37
28
  Object.defineProperty(exports, "__esModule", { value: true });
38
29
  exports.DefaultApiKeyManager = void 0;
39
- const fs = __importStar(require("fs"));
40
- const path = __importStar(require("path"));
41
- const os = __importStar(require("os"));
30
+ const fs = __importStar(require("node:fs"));
31
+ const os = __importStar(require("node:os"));
32
+ const path = __importStar(require("node:path"));
33
+ const node_readline_1 = __importDefault(require("node:readline"));
42
34
  const api_key_service_1 = require("../services/api-key-service");
43
- const readline_1 = __importDefault(require("readline"));
44
35
  const logger_1 = require("./logger");
45
36
  /**
46
37
  * Manages the default API key for chat commands
47
38
  */
48
39
  class DefaultApiKeyManager {
40
+ static instance;
41
+ configFilePath;
42
+ defaultApiKey = null;
49
43
  constructor() {
50
- this.defaultApiKey = null;
51
44
  // Set up config file path in user's home directory
52
45
  const bergetDir = path.join(os.homedir(), '.berget');
53
46
  if (!fs.existsSync(bergetDir)) {
@@ -62,6 +55,121 @@ class DefaultApiKeyManager {
62
55
  }
63
56
  return DefaultApiKeyManager.instance;
64
57
  }
58
+ /**
59
+ * Clear the default API key
60
+ */
61
+ clearDefaultApiKey() {
62
+ this.defaultApiKey = null;
63
+ this.saveConfig();
64
+ }
65
+ /**
66
+ * Get the default API key string
67
+ */
68
+ getDefaultApiKey() {
69
+ return this.defaultApiKey?.key || null;
70
+ }
71
+ /**
72
+ * Get the default API key data object
73
+ */
74
+ getDefaultApiKeyData() {
75
+ return this.defaultApiKey;
76
+ }
77
+ /**
78
+ * Prompts the user to select a default API key if none is set
79
+ * @returns The selected API key or null if none was selected
80
+ */
81
+ async promptForDefaultApiKey() {
82
+ try {
83
+ logger_1.logger.debug('promptForDefaultApiKey called');
84
+ // If we already have a default API key, return it
85
+ if (this.defaultApiKey) {
86
+ logger_1.logger.debug('Using existing default API key');
87
+ return this.defaultApiKey.key;
88
+ }
89
+ logger_1.logger.debug('No default API key found, getting ApiKeyService');
90
+ const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
91
+ // Get all API keys
92
+ let apiKeys;
93
+ try {
94
+ logger_1.logger.debug('Calling apiKeyService.list()');
95
+ apiKeys = await apiKeyService.list();
96
+ logger_1.logger.debug(`Got ${apiKeys ? apiKeys.length : 0} API keys`);
97
+ if (!apiKeys || apiKeys.length === 0) {
98
+ logger_1.logger.warn('No API keys found. Create one with:');
99
+ logger_1.logger.info(' berget api-keys create --name "My Key"');
100
+ return null;
101
+ }
102
+ }
103
+ catch (error) {
104
+ // Check if this is an authentication error
105
+ const errorMessage = error instanceof Error ? error.message : String(error);
106
+ const isAuthError = errorMessage.includes('Unauthorized') ||
107
+ errorMessage.includes('Authentication failed') ||
108
+ errorMessage.includes('AUTH_FAILED');
109
+ if (isAuthError) {
110
+ logger_1.logger.warn('Authentication required. Please run `berget auth login` first.');
111
+ }
112
+ else {
113
+ logger_1.logger.error('Error fetching API keys:');
114
+ if (error instanceof Error) {
115
+ logger_1.logger.error(error.message);
116
+ logger_1.logger.debug(`API key list error: ${error.message}`);
117
+ logger_1.logger.debug(`Stack: ${error.stack}`);
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ logger_1.logger.info('Select an API key to use as default:');
123
+ // Display available API keys
124
+ for (const [index, key] of apiKeys.entries()) {
125
+ logger_1.logger.log(` ${index + 1}. ${key.name} (${key.prefix}...)`);
126
+ }
127
+ // Create readline interface for user input
128
+ const rl = node_readline_1.default.createInterface({
129
+ input: process.stdin,
130
+ output: process.stdout,
131
+ });
132
+ // Prompt for selection
133
+ const selection = await new Promise((resolve) => {
134
+ rl.question('Enter number (or press Enter to cancel): ', (answer) => {
135
+ rl.close();
136
+ const number_ = Number.parseInt(answer.trim(), 10);
137
+ if (isNaN(number_) || number_ < 1 || number_ > apiKeys.length) {
138
+ resolve(-1); // Invalid selection
139
+ }
140
+ else {
141
+ resolve(number_ - 1); // Convert to zero-based index
142
+ }
143
+ });
144
+ });
145
+ if (selection === -1) {
146
+ logger_1.logger.warn('No API key selected');
147
+ return null;
148
+ }
149
+ const selectedKey = apiKeys[selection];
150
+ // Create a new API key with the selected name
151
+ const newKey = await apiKeyService.create({
152
+ description: 'Created automatically by the Berget CLI for default use',
153
+ name: `CLI Default (copy of ${selectedKey.name})`,
154
+ });
155
+ // Save the new key as default
156
+ this.setDefaultApiKey(newKey.id.toString(), newKey.name, newKey.key.slice(0, 8), // Use first 8 chars as prefix
157
+ newKey.key);
158
+ logger_1.logger.success(`✓ Default API key set to: ${newKey.name}`);
159
+ return newKey.key;
160
+ }
161
+ catch (error) {
162
+ logger_1.logger.error('Failed to set default API key:', error);
163
+ return null;
164
+ }
165
+ }
166
+ /**
167
+ * Set the default API key
168
+ */
169
+ setDefaultApiKey(id, name, prefix, key) {
170
+ this.defaultApiKey = { id, key, name, prefix };
171
+ this.saveConfig();
172
+ }
65
173
  /**
66
174
  * Load default API key from file
67
175
  */
@@ -72,7 +180,7 @@ class DefaultApiKeyManager {
72
180
  this.defaultApiKey = JSON.parse(data);
73
181
  }
74
182
  }
75
- catch (error) {
183
+ catch {
76
184
  logger_1.logger.debug('Failed to load default API key configuration');
77
185
  this.defaultApiKey = null;
78
186
  }
@@ -94,127 +202,9 @@ class DefaultApiKeyManager {
94
202
  }
95
203
  }
96
204
  }
97
- catch (error) {
205
+ catch {
98
206
  logger_1.logger.debug('Failed to save default API key configuration');
99
207
  }
100
208
  }
101
- /**
102
- * Set the default API key
103
- */
104
- setDefaultApiKey(id, name, prefix, key) {
105
- this.defaultApiKey = { id, name, prefix, key };
106
- this.saveConfig();
107
- }
108
- /**
109
- * Get the default API key string
110
- */
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() {
119
- return this.defaultApiKey;
120
- }
121
- /**
122
- * Clear the default API key
123
- */
124
- clearDefaultApiKey() {
125
- this.defaultApiKey = null;
126
- this.saveConfig();
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
- }
219
209
  }
220
210
  exports.DefaultApiKeyManager = DefaultApiKeyManager;