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
@@ -10,16 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.KubectlService = void 0;
13
- const client_1 = require("../client");
14
13
  const command_structure_1 = require("../constants/command-structure");
15
14
  /**
16
15
  * Service for managing Kubernetes resources
17
16
  * Command group: kubectl
18
17
  */
19
18
  class KubectlService {
20
- constructor() {
21
- this.client = (0, client_1.createAuthenticatedClient)();
22
- }
19
+ constructor() { }
23
20
  static getInstance() {
24
21
  if (!KubectlService.instance) {
25
22
  KubectlService.instance = new KubectlService();
@@ -31,9 +28,9 @@ class KubectlService {
31
28
  * Command: berget kubectl create-namespace
32
29
  * This endpoint is not available in the API
33
30
  */
34
- createNamespace(name) {
31
+ createNamespace(_name) {
35
32
  return __awaiter(this, void 0, void 0, function* () {
36
- throw new Error('This functionality is not available in the API');
33
+ throw new Error("This functionality is not available in the API");
37
34
  });
38
35
  }
39
36
  /**
@@ -41,9 +38,9 @@ class KubectlService {
41
38
  * Command: berget kubectl apply
42
39
  * This endpoint is not available in the API
43
40
  */
44
- apply(filename) {
41
+ apply(_filename) {
45
42
  return __awaiter(this, void 0, void 0, function* () {
46
- throw new Error('This functionality is not available in the API');
43
+ throw new Error("This functionality is not available in the API");
47
44
  });
48
45
  }
49
46
  /**
@@ -51,9 +48,9 @@ class KubectlService {
51
48
  * Command: berget kubectl get
52
49
  * This endpoint is not available in the API
53
50
  */
54
- get(resource, namespace) {
51
+ get(_resource, _namespace) {
55
52
  return __awaiter(this, void 0, void 0, function* () {
56
- throw new Error('This functionality is not available in the API');
53
+ throw new Error("This functionality is not available in the API");
57
54
  });
58
55
  }
59
56
  }
@@ -30,19 +30,19 @@ const path = __importStar(require("path"));
30
30
  * Check for .bergetconfig file and handle cluster switching
31
31
  */
32
32
  function checkBergetConfig() {
33
- const configPath = path.join(process.cwd(), '.bergetconfig');
33
+ const configPath = path.join(process.cwd(), ".bergetconfig");
34
34
  if (fs.existsSync(configPath)) {
35
35
  try {
36
- const config = fs.readFileSync(configPath, 'utf8');
36
+ const config = fs.readFileSync(configPath, "utf8");
37
37
  const match = config.match(/cluster:\s*(.+)/);
38
38
  if (match && match[1]) {
39
39
  const clusterName = match[1].trim();
40
40
  console.log(`🔄 Berget: Switched to cluster "${clusterName}"`);
41
- console.log('✓ kubectl config updated');
42
- console.log('');
41
+ console.log("✓ kubectl config updated");
42
+ console.log("");
43
43
  }
44
44
  }
45
- catch (error) {
45
+ catch (_a) {
46
46
  // Silently ignore errors reading config
47
47
  }
48
48
  }
@@ -31,7 +31,7 @@ class ConfigLoader {
31
31
  constructor(configPath) {
32
32
  this.config = null;
33
33
  // Default to opencode.json in current working directory
34
- this.configPath = configPath || path.join(process.cwd(), 'opencode.json');
34
+ this.configPath = configPath || path.join(process.cwd(), "opencode.json");
35
35
  }
36
36
  static getInstance(configPath) {
37
37
  if (!ConfigLoader.instance) {
@@ -56,7 +56,7 @@ class ConfigLoader {
56
56
  if (!fs.existsSync(this.configPath)) {
57
57
  throw new Error(`Configuration file not found: ${this.configPath}`);
58
58
  }
59
- const configContent = fs.readFileSync(this.configPath, 'utf8');
59
+ const configContent = fs.readFileSync(this.configPath, "utf8");
60
60
  this.config = JSON.parse(configContent);
61
61
  logger_1.logger.debug(`Loaded configuration from ${this.configPath}`);
62
62
  return this.config;
@@ -75,7 +75,7 @@ class ConfigLoader {
75
75
  const config = this.loadConfig();
76
76
  return ((_a = config.agent) === null || _a === void 0 ? void 0 : _a[agentName]) || null;
77
77
  }
78
- catch (error) {
78
+ catch (_b) {
79
79
  // Config file doesn't exist, return null
80
80
  return null;
81
81
  }
@@ -88,7 +88,7 @@ class ConfigLoader {
88
88
  const config = this.loadConfig();
89
89
  return config.agent || {};
90
90
  }
91
- catch (error) {
91
+ catch (_a) {
92
92
  // Config file doesn't exist, return empty object
93
93
  return {};
94
94
  }
@@ -100,15 +100,15 @@ class ConfigLoader {
100
100
  try {
101
101
  const config = this.loadConfig();
102
102
  // Extract from config or fall back to defaults
103
- const primary = config.model || 'berget/glm-4.7';
104
- const small = config.small_model || 'berget/gpt-oss';
103
+ const primary = config.model || "berget/glm-4.7";
104
+ const small = config.small_model || "berget/gpt-oss";
105
105
  return { primary, small };
106
106
  }
107
- catch (error) {
107
+ catch (_a) {
108
108
  // Fallback to defaults when no config exists (init scenario)
109
109
  return {
110
- primary: 'berget/glm-4.7',
111
- small: 'berget/gpt-oss',
110
+ primary: "berget/glm-4.7",
111
+ small: "berget/gpt-oss",
112
112
  };
113
113
  }
114
114
  }
@@ -124,25 +124,25 @@ class ConfigLoader {
124
124
  return config.provider.berget.models;
125
125
  }
126
126
  }
127
- catch (error) {
127
+ catch (_c) {
128
128
  // Config file doesn't exist, use fallback defaults
129
129
  }
130
130
  // Fallback to defaults
131
131
  return {
132
- 'glm-4.7': {
133
- name: 'GLM-4.7',
132
+ "glm-4.7": {
133
+ name: "GLM-4.7",
134
134
  limit: { output: 4000, context: 90000 },
135
135
  },
136
- 'gpt-oss': {
137
- name: 'GPT-OSS',
136
+ "gpt-oss": {
137
+ name: "GPT-OSS",
138
138
  limit: { output: 4000, context: 128000 },
139
139
  modalities: {
140
- input: ['text', 'image'],
141
- output: ['text'],
140
+ input: ["text", "image"],
141
+ output: ["text"],
142
142
  },
143
143
  },
144
- 'llama-8b': {
145
- name: 'llama-3.1-8b',
144
+ "llama-8b": {
145
+ name: "llama-3.1-8b",
146
146
  limit: { output: 4000, context: 128000 },
147
147
  },
148
148
  };
@@ -155,7 +155,7 @@ class ConfigLoader {
155
155
  const config = this.loadConfig();
156
156
  return config.command || {};
157
157
  }
158
- catch (error) {
158
+ catch (_a) {
159
159
  // Config file doesn't exist, return empty object
160
160
  return {};
161
161
  }
@@ -167,12 +167,12 @@ class ConfigLoader {
167
167
  try {
168
168
  const config = this.loadConfig();
169
169
  return (config.watcher || {
170
- ignore: ['node_modules', 'dist', '.git', 'coverage'],
170
+ ignore: ["node_modules", "dist", ".git", "coverage"],
171
171
  });
172
172
  }
173
- catch (error) {
173
+ catch (_a) {
174
174
  // Config file doesn't exist, return default watcher config
175
- return { ignore: ['node_modules', 'dist', '.git', 'coverage'] };
175
+ return { ignore: ["node_modules", "dist", ".git", "coverage"] };
176
176
  }
177
177
  }
178
178
  /**
@@ -183,7 +183,7 @@ class ConfigLoader {
183
183
  const config = this.loadConfig();
184
184
  return config.provider || {};
185
185
  }
186
- catch (error) {
186
+ catch (_a) {
187
187
  // Config file doesn't exist, return empty object
188
188
  return {};
189
189
  }
@@ -205,14 +205,14 @@ class ConfigLoader {
205
205
  */
206
206
  getPrimaryAgentNames() {
207
207
  const agents = this.getAllAgentConfigs();
208
- return Object.keys(agents).filter((name) => agents[name].mode === 'primary');
208
+ return Object.keys(agents).filter(name => agents[name].mode === "primary");
209
209
  }
210
210
  /**
211
211
  * Get list of subagents (mode: 'subagent')
212
212
  */
213
213
  getSubagentNames() {
214
214
  const agents = this.getAllAgentConfigs();
215
- return Object.keys(agents).filter((name) => agents[name].mode === 'subagent');
215
+ return Object.keys(agents).filter(name => agents[name].mode === "subagent");
216
216
  }
217
217
  /**
218
218
  * Reload configuration from file
@@ -49,11 +49,11 @@ class DefaultApiKeyManager {
49
49
  constructor() {
50
50
  this.defaultApiKey = null;
51
51
  // Set up config file path in user's home directory
52
- const bergetDir = path.join(os.homedir(), '.berget');
52
+ const bergetDir = path.join(os.homedir(), ".berget");
53
53
  if (!fs.existsSync(bergetDir)) {
54
54
  fs.mkdirSync(bergetDir, { recursive: true });
55
55
  }
56
- this.configFilePath = path.join(bergetDir, 'default-api-key.json');
56
+ this.configFilePath = path.join(bergetDir, "default-api-key.json");
57
57
  this.loadConfig();
58
58
  }
59
59
  static getInstance() {
@@ -68,12 +68,12 @@ class DefaultApiKeyManager {
68
68
  loadConfig() {
69
69
  try {
70
70
  if (fs.existsSync(this.configFilePath)) {
71
- const data = fs.readFileSync(this.configFilePath, 'utf8');
71
+ const data = fs.readFileSync(this.configFilePath, "utf8");
72
72
  this.defaultApiKey = JSON.parse(data);
73
73
  }
74
74
  }
75
- catch (error) {
76
- logger_1.logger.debug('Failed to load default API key configuration');
75
+ catch (_a) {
76
+ logger_1.logger.debug("Failed to load default API key configuration");
77
77
  this.defaultApiKey = null;
78
78
  }
79
79
  }
@@ -94,8 +94,8 @@ class DefaultApiKeyManager {
94
94
  }
95
95
  }
96
96
  }
97
- catch (error) {
98
- logger_1.logger.debug('Failed to save default API key configuration');
97
+ catch (_a) {
98
+ logger_1.logger.debug("Failed to save default API key configuration");
99
99
  }
100
100
  }
101
101
  /**
@@ -132,22 +132,22 @@ class DefaultApiKeyManager {
132
132
  promptForDefaultApiKey() {
133
133
  return __awaiter(this, void 0, void 0, function* () {
134
134
  try {
135
- logger_1.logger.debug('promptForDefaultApiKey called');
135
+ logger_1.logger.debug("promptForDefaultApiKey called");
136
136
  // If we already have a default API key, return it
137
137
  if (this.defaultApiKey) {
138
- logger_1.logger.debug('Using existing default API key');
138
+ logger_1.logger.debug("Using existing default API key");
139
139
  return this.defaultApiKey.key;
140
140
  }
141
- logger_1.logger.debug('No default API key found, getting ApiKeyService');
141
+ logger_1.logger.debug("No default API key found, getting ApiKeyService");
142
142
  const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
143
143
  // Get all API keys
144
144
  let apiKeys;
145
145
  try {
146
- logger_1.logger.debug('Calling apiKeyService.list()');
146
+ logger_1.logger.debug("Calling apiKeyService.list()");
147
147
  apiKeys = yield apiKeyService.list();
148
148
  logger_1.logger.debug(`Got ${apiKeys ? apiKeys.length : 0} API keys`);
149
149
  if (!apiKeys || apiKeys.length === 0) {
150
- logger_1.logger.warn('No API keys found. Create one with:');
150
+ logger_1.logger.warn("No API keys found. Create one with:");
151
151
  logger_1.logger.info(' berget api-keys create --name "My Key"');
152
152
  return null;
153
153
  }
@@ -155,14 +155,14 @@ class DefaultApiKeyManager {
155
155
  catch (error) {
156
156
  // Check if this is an authentication error
157
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');
158
+ const isAuthError = errorMessage.includes("Unauthorized") ||
159
+ errorMessage.includes("Authentication failed") ||
160
+ errorMessage.includes("AUTH_FAILED");
161
161
  if (isAuthError) {
162
- logger_1.logger.warn('Authentication required. Please run `berget auth login` first.');
162
+ logger_1.logger.warn("Authentication required. Please run `berget auth login` first.");
163
163
  }
164
164
  else {
165
- logger_1.logger.error('Error fetching API keys:');
165
+ logger_1.logger.error("Error fetching API keys:");
166
166
  if (error instanceof Error) {
167
167
  logger_1.logger.error(error.message);
168
168
  logger_1.logger.debug(`API key list error: ${error.message}`);
@@ -171,7 +171,7 @@ class DefaultApiKeyManager {
171
171
  }
172
172
  return null;
173
173
  }
174
- logger_1.logger.info('Select an API key to use as default:');
174
+ logger_1.logger.info("Select an API key to use as default:");
175
175
  // Display available API keys
176
176
  apiKeys.forEach((key, index) => {
177
177
  logger_1.logger.log(` ${index + 1}. ${key.name} (${key.prefix}...)`);
@@ -182,8 +182,8 @@ class DefaultApiKeyManager {
182
182
  output: process.stdout,
183
183
  });
184
184
  // Prompt for selection
185
- const selection = yield new Promise((resolve) => {
186
- rl.question('Enter number (or press Enter to cancel): ', (answer) => {
185
+ const selection = yield new Promise(resolve => {
186
+ rl.question("Enter number (or press Enter to cancel): ", answer => {
187
187
  rl.close();
188
188
  const num = parseInt(answer.trim(), 10);
189
189
  if (isNaN(num) || num < 1 || num > apiKeys.length) {
@@ -195,14 +195,14 @@ class DefaultApiKeyManager {
195
195
  });
196
196
  });
197
197
  if (selection === -1) {
198
- logger_1.logger.warn('No API key selected');
198
+ logger_1.logger.warn("No API key selected");
199
199
  return null;
200
200
  }
201
201
  const selectedKey = apiKeys[selection];
202
202
  // Create a new API key with the selected name
203
203
  const newKey = yield apiKeyService.create({
204
204
  name: `CLI Default (copy of ${selectedKey.name})`,
205
- description: 'Created automatically by the Berget CLI for default use',
205
+ description: "Created automatically by the Berget CLI for default use",
206
206
  });
207
207
  // Save the new key as default
208
208
  this.setDefaultApiKey(newKey.id.toString(), newKey.name, newKey.key.substring(0, 8), // Use first 8 chars as prefix
@@ -211,7 +211,7 @@ class DefaultApiKeyManager {
211
211
  return newKey.key;
212
212
  }
213
213
  catch (error) {
214
- logger_1.logger.error('Failed to set default API key:', error);
214
+ logger_1.logger.error("Failed to set default API key:", error);
215
215
  return null;
216
216
  }
217
217
  });
@@ -24,13 +24,13 @@ const dotenv_1 = __importDefault(require("dotenv"));
24
24
  */
25
25
  function updateEnvFile(options) {
26
26
  return __awaiter(this, void 0, void 0, function* () {
27
- const { envPath = path_1.default.join(process.cwd(), '.env'), key, value, comment, force = false, } = options;
27
+ const { envPath = path_1.default.join(process.cwd(), ".env"), key, value, comment, force = false, } = options;
28
28
  try {
29
- let existingContent = '';
29
+ let existingContent = "";
30
30
  let parsed = {};
31
31
  // Read existing .env file if it exists
32
32
  if (fs_1.default.existsSync(envPath)) {
33
- existingContent = fs_1.default.readFileSync(envPath, 'utf8');
33
+ existingContent = fs_1.default.readFileSync(envPath, "utf8");
34
34
  parsed = dotenv_1.default.parse(existingContent);
35
35
  }
36
36
  // Check if key already exists and we're not forcing
@@ -41,7 +41,7 @@ function updateEnvFile(options) {
41
41
  // Update the parsed object
42
42
  parsed[key] = value;
43
43
  // Generate new .env content
44
- let newContent = '';
44
+ let newContent = "";
45
45
  // Add comment at the top if this is a new file
46
46
  if (!existingContent && comment) {
47
47
  newContent += `# ${comment}\n`;
@@ -51,7 +51,7 @@ function updateEnvFile(options) {
51
51
  newContent += `${envKey}=${envValue}\n`;
52
52
  }
53
53
  // Write the updated content
54
- yield (0, promises_1.writeFile)(envPath, newContent.trim() + '\n');
54
+ yield (0, promises_1.writeFile)(envPath, newContent.trim() + "\n");
55
55
  if (existingContent) {
56
56
  console.log(chalk_1.default.green(`✓ Updated .env with ${key}`));
57
57
  }
@@ -70,12 +70,12 @@ exports.updateEnvFile = updateEnvFile;
70
70
  /**
71
71
  * Checks if a .env file exists and contains a specific key
72
72
  */
73
- function hasEnvKey(envPath = path_1.default.join(process.cwd(), '.env'), key) {
73
+ function hasEnvKey(envPath = path_1.default.join(process.cwd(), ".env"), key) {
74
74
  if (!fs_1.default.existsSync(envPath)) {
75
75
  return false;
76
76
  }
77
77
  try {
78
- const content = fs_1.default.readFileSync(envPath, 'utf8');
78
+ const content = fs_1.default.readFileSync(envPath, "utf8");
79
79
  const parsed = dotenv_1.default.parse(content);
80
80
  return key in parsed;
81
81
  }
@@ -10,18 +10,18 @@ const chalk_1 = __importDefault(require("chalk"));
10
10
  */
11
11
  function handleError(message, error) {
12
12
  console.error(chalk_1.default.red(`❌ Error: ${message}`));
13
- let errorDetails = '';
14
- let errorCode = '';
15
- let errorType = '';
13
+ let errorDetails = "";
14
+ let errorCode = "";
15
+ let errorType = "";
16
16
  // If the error is a string (like JSON.stringify(error))
17
- if (typeof error === 'string') {
17
+ if (typeof error === "string") {
18
18
  try {
19
19
  // Try to parse it as JSON
20
20
  const parsedError = JSON.parse(error);
21
21
  if (parsedError.error) {
22
22
  errorDetails = parsedError.error.message || parsedError.error;
23
23
  errorCode = parsedError.error.code || parsedError.code;
24
- errorType = parsedError.error.type || '';
24
+ errorType = parsedError.error.type || "";
25
25
  }
26
26
  else {
27
27
  errorDetails = error;
@@ -53,76 +53,75 @@ exports.handleError = handleError;
53
53
  * Provides helpful troubleshooting tips based on error type
54
54
  */
55
55
  function provideTroubleshootingTips(errorType, errorCode, errorDetails) {
56
- console.error(chalk_1.default.blue('\n💡 Troubleshooting tips:'));
56
+ console.error(chalk_1.default.blue("\n💡 Troubleshooting tips:"));
57
57
  // Authentication errors
58
- if (errorType === 'authentication_error' ||
59
- errorCode === 'AUTH_FAILED' ||
60
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('Unauthorized')) ||
61
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('Authentication failed'))) {
62
- console.error(chalk_1.default.yellow(' 🔐 Authentication issue detected:'));
63
- console.error(chalk_1.default.white(' • Run `berget auth login` to log in'));
64
- console.error(chalk_1.default.white(' • Check if your session has expired'));
65
- console.error(chalk_1.default.white(' • Verify you have the correct permissions'));
58
+ if (errorType === "authentication_error" ||
59
+ errorCode === "AUTH_FAILED" ||
60
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("Unauthorized")) ||
61
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("Authentication failed"))) {
62
+ console.error(chalk_1.default.yellow(" 🔐 Authentication issue detected:"));
63
+ console.error(chalk_1.default.white(" • Run `berget auth login` to log in"));
64
+ console.error(chalk_1.default.white(" • Check if your session has expired"));
65
+ console.error(chalk_1.default.white(" • Verify you have the correct permissions"));
66
66
  }
67
67
  // Network/connection errors
68
- if ((errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('fetch failed')) ||
69
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('ECONNREFUSED')) ||
70
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('ENOTFOUND')) ||
71
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('network'))) {
72
- console.error(chalk_1.default.yellow(' 🌐 Network issue detected:'));
73
- console.error(chalk_1.default.white(' • Check your internet connection'));
74
- console.error(chalk_1.default.white(' • Verify you can reach api.berget.ai'));
75
- console.error(chalk_1.default.white(' • Try again in a few minutes'));
76
- console.error(chalk_1.default.white(' • Check if any firewall is blocking the request'));
68
+ if ((errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("fetch failed")) ||
69
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("ECONNREFUSED")) ||
70
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("ENOTFOUND")) ||
71
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("network"))) {
72
+ console.error(chalk_1.default.yellow(" 🌐 Network issue detected:"));
73
+ console.error(chalk_1.default.white(" • Check your internet connection"));
74
+ console.error(chalk_1.default.white(" • Verify you can reach api.berget.ai"));
75
+ console.error(chalk_1.default.white(" • Try again in a few minutes"));
76
+ console.error(chalk_1.default.white(" • Check if any firewall is blocking the request"));
77
77
  }
78
78
  // API key errors
79
- if ((errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('API_KEY')) ||
80
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('API key')) ||
81
- errorType === 'invalid_request_error') {
82
- console.error(chalk_1.default.yellow(' 🔑 API key issue detected:'));
83
- console.error(chalk_1.default.white(' • Run `berget api-keys list` to check your keys'));
79
+ if ((errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("API_KEY")) ||
80
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("API key")) ||
81
+ errorType === "invalid_request_error") {
82
+ console.error(chalk_1.default.yellow(" 🔑 API key issue detected:"));
83
+ console.error(chalk_1.default.white(" • Run `berget api-keys list` to check your keys"));
84
84
  console.error(chalk_1.default.white(' • Create a new key with `berget api-keys create --name "My Key"`'));
85
- console.error(chalk_1.default.white(' • Set a default key with `berget api-keys set-default <id>`'));
86
- console.error(chalk_1.default.white(' • Check if your API key has expired'));
85
+ console.error(chalk_1.default.white(" • Set a default key with `berget api-keys set-default <id>`"));
86
+ console.error(chalk_1.default.white(" • Check if your API key has expired"));
87
87
  }
88
88
  // Rate limiting
89
- if (errorCode === 'RATE_LIMIT_EXCEEDED' ||
90
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('rate limit')) ||
91
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('too many requests'))) {
92
- console.error(chalk_1.default.yellow(' ⏱️ Rate limit exceeded:'));
93
- console.error(chalk_1.default.white(' • Wait a few minutes before trying again'));
94
- console.error(chalk_1.default.white(' • Consider upgrading your plan for higher limits'));
95
- console.error(chalk_1.default.white(' • Use `berget billing get-usage` to check your usage'));
89
+ if (errorCode === "RATE_LIMIT_EXCEEDED" ||
90
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("rate limit")) ||
91
+ (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("too many requests"))) {
92
+ console.error(chalk_1.default.yellow(" ⏱️ Rate limit exceeded:"));
93
+ console.error(chalk_1.default.white(" • Wait a few minutes before trying again"));
94
+ console.error(chalk_1.default.white(" • Consider upgrading your plan for higher limits"));
95
+ console.error(chalk_1.default.white(" • Use `berget billing get-usage` to check your usage"));
96
96
  }
97
97
  // Server errors
98
- if ((errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('SERVER_ERROR')) ||
99
- errorType === 'server_error' ||
98
+ if ((errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("SERVER_ERROR")) ||
99
+ errorType === "server_error" ||
100
100
  (errorCode && parseInt(errorCode) >= 500)) {
101
- console.error(chalk_1.default.yellow(' 🖥️ Server issue detected:'));
102
- console.error(chalk_1.default.white(' • This is a temporary problem on our end'));
103
- console.error(chalk_1.default.white(' • Try again in a few minutes'));
104
- console.error(chalk_1.default.white(' • Check status.berget.ai for service status'));
105
- console.error(chalk_1.default.white(' • Contact support if the problem persists'));
101
+ console.error(chalk_1.default.yellow(" 🖥️ Server issue detected:"));
102
+ console.error(chalk_1.default.white(" • This is a temporary problem on our end"));
103
+ console.error(chalk_1.default.white(" • Try again in a few minutes"));
104
+ console.error(chalk_1.default.white(" • Check status.berget.ai for service status"));
105
+ console.error(chalk_1.default.white(" • Contact support if the problem persists"));
106
106
  }
107
107
  // Cluster errors
108
- if ((errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('CLUSTERS')) ||
109
- (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('cluster'))) {
110
- console.error(chalk_1.default.yellow(' 🏗️ Cluster issue detected:'));
111
- console.error(chalk_1.default.white('Clusters may be temporarily unavailable'));
112
- console.error(chalk_1.default.white('Try again later or contact support'));
113
- console.error(chalk_1.default.white(' • Check your cluster permissions'));
108
+ if ((errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("CLUSTERS")) || (errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("cluster"))) {
109
+ console.error(chalk_1.default.yellow(" 🏗️ Cluster issue detected:"));
110
+ console.error(chalk_1.default.white(" Clusters may be temporarily unavailable"));
111
+ console.error(chalk_1.default.white("Try again later or contact support"));
112
+ console.error(chalk_1.default.white("Check your cluster permissions"));
114
113
  }
115
114
  // Generic fallback
116
- if (!(errorType === null || errorType === void 0 ? void 0 : errorType.includes('authentication')) &&
117
- !(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes('fetch failed')) &&
118
- !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('API_KEY')) &&
119
- !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('RATE_LIMIT')) &&
120
- !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('SERVER_ERROR')) &&
121
- !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes('CLUSTERS'))) {
122
- console.error(chalk_1.default.yellow(' ❓ General issue:'));
123
- console.error(chalk_1.default.white(' • Try running the command with --debug for more info'));
124
- console.error(chalk_1.default.white(' • Check your configuration with `berget auth whoami`'));
125
- console.error(chalk_1.default.white(' • Contact support if the problem persists'));
115
+ if (!(errorType === null || errorType === void 0 ? void 0 : errorType.includes("authentication")) &&
116
+ !(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes("fetch failed")) &&
117
+ !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("API_KEY")) &&
118
+ !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("RATE_LIMIT")) &&
119
+ !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("SERVER_ERROR")) &&
120
+ !(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes("CLUSTERS"))) {
121
+ console.error(chalk_1.default.yellow(" ❓ General issue:"));
122
+ console.error(chalk_1.default.white(" • Try running the command with --debug for more info"));
123
+ console.error(chalk_1.default.white(" • Check your configuration with `berget auth whoami`"));
124
+ console.error(chalk_1.default.white(" • Contact support if the problem persists"));
126
125
  }
127
- console.error(chalk_1.default.dim('\nNeed more help? Visit https://docs.berget.ai or contact support@berget.ai'));
126
+ console.error(chalk_1.default.dim("\nNeed more help? Visit https://docs.berget.ai or contact support@berget.ai"));
128
127
  }
@@ -26,10 +26,10 @@ class Logger {
26
26
  if (process.env.LOG_LEVEL) {
27
27
  this.setLogLevelFromString(process.env.LOG_LEVEL);
28
28
  }
29
- else if (process.argv.includes('--debug')) {
29
+ else if (process.argv.includes("--debug")) {
30
30
  this.logLevel = LogLevel.DEBUG;
31
31
  }
32
- else if (process.argv.includes('--quiet')) {
32
+ else if (process.argv.includes("--quiet")) {
33
33
  this.logLevel = LogLevel.ERROR;
34
34
  }
35
35
  }
@@ -44,19 +44,19 @@ class Logger {
44
44
  */
45
45
  setLogLevelFromString(level) {
46
46
  switch (level.toLowerCase()) {
47
- case 'none':
47
+ case "none":
48
48
  this.logLevel = LogLevel.NONE;
49
49
  break;
50
- case 'error':
50
+ case "error":
51
51
  this.logLevel = LogLevel.ERROR;
52
52
  break;
53
- case 'warn':
53
+ case "warn":
54
54
  this.logLevel = LogLevel.WARN;
55
55
  break;
56
- case 'info':
56
+ case "info":
57
57
  this.logLevel = LogLevel.INFO;
58
58
  break;
59
- case 'debug':
59
+ case "debug":
60
60
  this.logLevel = LogLevel.DEBUG;
61
61
  break;
62
62
  default:
@@ -33,7 +33,7 @@ marked_1.marked.setOptions({
33
33
  */
34
34
  function renderMarkdown(markdown) {
35
35
  if (!markdown)
36
- return '';
36
+ return "";
37
37
  try {
38
38
  // Convert markdown to terminal-friendly text
39
39
  return (0, marked_1.marked)(markdown);
@@ -68,6 +68,6 @@ function containsMarkdown(text) {
68
68
  /^---+$/m, // Horizontal rules
69
69
  /^===+$/m, // Alternative headers
70
70
  ];
71
- return markdownPatterns.some((pattern) => pattern.test(text));
71
+ return markdownPatterns.some(pattern => pattern.test(text));
72
72
  }
73
73
  exports.containsMarkdown = containsMarkdown;