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.
- package/.github/workflows/publish.yml +6 -6
- package/.github/workflows/test.yml +11 -5
- package/.husky/pre-commit +1 -0
- package/.prettierignore +15 -0
- package/.prettierrc +5 -3
- package/CONTRIBUTING.md +38 -0
- package/README.md +2 -148
- package/dist/index.js +21 -21
- package/dist/package.json +28 -2
- package/dist/src/agents/app.js +28 -0
- package/dist/src/agents/backend.js +25 -0
- package/dist/src/agents/devops.js +34 -0
- package/dist/src/agents/frontend.js +25 -0
- package/dist/src/agents/fullstack.js +25 -0
- package/dist/src/agents/index.js +61 -0
- package/dist/src/agents/quality.js +70 -0
- package/dist/src/agents/security.js +26 -0
- package/dist/src/agents/types.js +2 -0
- package/dist/src/client.js +54 -62
- package/dist/src/commands/api-keys.js +132 -140
- package/dist/src/commands/auth.js +9 -9
- package/dist/src/commands/autocomplete.js +9 -9
- package/dist/src/commands/billing.js +7 -9
- package/dist/src/commands/chat.js +90 -92
- package/dist/src/commands/clusters.js +12 -12
- package/dist/src/commands/code/__tests__/auth-sync.test.js +348 -0
- package/dist/src/commands/code/__tests__/fake-api-key-service.js +23 -0
- package/dist/src/commands/code/__tests__/fake-auth-service.js +55 -0
- package/dist/src/commands/code/__tests__/fake-command-runner.js +5 -7
- package/dist/src/commands/code/__tests__/fake-file-store.js +9 -0
- package/dist/src/commands/code/__tests__/fake-prompter.js +60 -18
- package/dist/src/commands/code/__tests__/setup-flow.test.js +374 -107
- package/dist/src/commands/code/adapters/clack-prompter.js +10 -0
- package/dist/src/commands/code/adapters/fs-file-store.js +8 -3
- package/dist/src/commands/code/adapters/spawn-command-runner.js +15 -11
- package/dist/src/commands/code/auth-sync.js +283 -0
- package/dist/src/commands/code/errors.js +4 -4
- package/dist/src/commands/code/ports/auth-services.js +2 -0
- package/dist/src/commands/code/setup.js +234 -93
- package/dist/src/commands/code.js +139 -251
- package/dist/src/commands/models.js +13 -15
- package/dist/src/commands/users.js +6 -8
- package/dist/src/constants/command-structure.js +116 -116
- package/dist/src/services/api-key-service.js +43 -48
- package/dist/src/services/auth-service.js +60 -299
- package/dist/src/services/browser-auth.js +278 -0
- package/dist/src/services/chat-service.js +78 -91
- package/dist/src/services/cluster-service.js +6 -6
- package/dist/src/services/collaborator-service.js +5 -8
- package/dist/src/services/flux-service.js +5 -8
- package/dist/src/services/helm-service.js +5 -8
- package/dist/src/services/kubectl-service.js +7 -10
- package/dist/src/utils/config-checker.js +5 -5
- package/dist/src/utils/config-loader.js +25 -25
- package/dist/src/utils/default-api-key.js +23 -23
- package/dist/src/utils/env-manager.js +7 -7
- package/dist/src/utils/error-handler.js +60 -61
- package/dist/src/utils/logger.js +7 -7
- package/dist/src/utils/markdown-renderer.js +2 -2
- package/dist/src/utils/opencode-validator.js +17 -20
- package/dist/src/utils/token-manager.js +38 -11
- package/dist/tests/commands/chat.test.js +24 -24
- package/dist/tests/commands/code.test.js +147 -147
- package/dist/tests/utils/config-loader.test.js +114 -114
- package/dist/tests/utils/env-manager.test.js +57 -57
- package/dist/tests/utils/opencode-validator.test.js +33 -33
- package/dist/vitest.config.js +1 -1
- package/eslint.config.mjs +47 -0
- package/index.ts +42 -48
- package/package.json +28 -2
- package/src/agents/app.ts +27 -0
- package/src/agents/backend.ts +24 -0
- package/src/agents/devops.ts +33 -0
- package/src/agents/frontend.ts +24 -0
- package/src/agents/fullstack.ts +24 -0
- package/src/agents/index.ts +71 -0
- package/src/agents/quality.ts +69 -0
- package/src/agents/security.ts +26 -0
- package/src/agents/types.ts +17 -0
- package/src/client.ts +125 -167
- package/src/commands/api-keys.ts +261 -358
- package/src/commands/auth.ts +24 -30
- package/src/commands/autocomplete.ts +12 -12
- package/src/commands/billing.ts +22 -27
- package/src/commands/chat.ts +230 -323
- package/src/commands/clusters.ts +33 -33
- package/src/commands/code/__tests__/auth-sync.test.ts +481 -0
- package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
- package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
- package/src/commands/code/__tests__/fake-command-runner.ts +39 -42
- package/src/commands/code/__tests__/fake-file-store.ts +32 -23
- package/src/commands/code/__tests__/fake-prompter.ts +107 -69
- package/src/commands/code/__tests__/setup-flow.test.ts +624 -270
- package/src/commands/code/adapters/clack-prompter.ts +50 -38
- package/src/commands/code/adapters/fs-file-store.ts +31 -27
- package/src/commands/code/adapters/spawn-command-runner.ts +33 -29
- package/src/commands/code/auth-sync.ts +329 -0
- package/src/commands/code/errors.ts +15 -15
- package/src/commands/code/ports/auth-services.ts +14 -0
- package/src/commands/code/ports/command-runner.ts +8 -4
- package/src/commands/code/ports/file-store.ts +5 -4
- package/src/commands/code/ports/prompter.ts +24 -18
- package/src/commands/code/setup.ts +545 -317
- package/src/commands/code.ts +271 -473
- package/src/commands/index.ts +19 -19
- package/src/commands/models.ts +32 -37
- package/src/commands/users.ts +15 -22
- package/src/constants/command-structure.ts +119 -142
- package/src/services/api-key-service.ts +96 -113
- package/src/services/auth-service.ts +92 -339
- package/src/services/browser-auth.ts +296 -0
- package/src/services/chat-service.ts +246 -279
- package/src/services/cluster-service.ts +29 -32
- package/src/services/collaborator-service.ts +13 -18
- package/src/services/flux-service.ts +16 -18
- package/src/services/helm-service.ts +16 -18
- package/src/services/kubectl-service.ts +12 -14
- package/src/types/api.d.ts +924 -926
- package/src/types/json.d.ts +3 -3
- package/src/utils/config-checker.ts +10 -10
- package/src/utils/config-loader.ts +110 -127
- package/src/utils/default-api-key.ts +81 -93
- package/src/utils/env-manager.ts +36 -40
- package/src/utils/error-handler.ts +83 -78
- package/src/utils/logger.ts +41 -41
- package/src/utils/markdown-renderer.ts +11 -11
- package/src/utils/opencode-validator.ts +51 -56
- package/src/utils/token-manager.ts +84 -64
- package/templates/agents/app.md +1 -0
- package/templates/agents/backend.md +1 -0
- package/templates/agents/devops.md +2 -0
- package/templates/agents/frontend.md +1 -0
- package/templates/agents/fullstack.md +1 -0
- package/templates/agents/quality.md +45 -40
- package/templates/agents/security.md +1 -0
- package/tests/commands/chat.test.ts +60 -70
- package/tests/commands/code.test.ts +330 -376
- package/tests/utils/config-loader.test.ts +260 -260
- package/tests/utils/env-manager.test.ts +127 -134
- package/tests/utils/opencode-validator.test.ts +58 -63
- package/tsconfig.json +2 -2
- package/vitest.config.ts +3 -3
- package/AGENTS.md +0 -374
- 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(
|
|
31
|
+
createNamespace(_name) {
|
|
35
32
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
throw new Error(
|
|
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(
|
|
41
|
+
apply(_filename) {
|
|
45
42
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
-
throw new Error(
|
|
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(
|
|
51
|
+
get(_resource, _namespace) {
|
|
55
52
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
-
throw new Error(
|
|
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(),
|
|
33
|
+
const configPath = path.join(process.cwd(), ".bergetconfig");
|
|
34
34
|
if (fs.existsSync(configPath)) {
|
|
35
35
|
try {
|
|
36
|
-
const config = fs.readFileSync(configPath,
|
|
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(
|
|
42
|
-
console.log(
|
|
41
|
+
console.log("✓ kubectl config updated");
|
|
42
|
+
console.log("");
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
catch (
|
|
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(),
|
|
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,
|
|
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 (
|
|
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 (
|
|
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 ||
|
|
104
|
-
const small = config.small_model ||
|
|
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 (
|
|
107
|
+
catch (_a) {
|
|
108
108
|
// Fallback to defaults when no config exists (init scenario)
|
|
109
109
|
return {
|
|
110
|
-
primary:
|
|
111
|
-
small:
|
|
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 (
|
|
127
|
+
catch (_c) {
|
|
128
128
|
// Config file doesn't exist, use fallback defaults
|
|
129
129
|
}
|
|
130
130
|
// Fallback to defaults
|
|
131
131
|
return {
|
|
132
|
-
|
|
133
|
-
name:
|
|
132
|
+
"glm-4.7": {
|
|
133
|
+
name: "GLM-4.7",
|
|
134
134
|
limit: { output: 4000, context: 90000 },
|
|
135
135
|
},
|
|
136
|
-
|
|
137
|
-
name:
|
|
136
|
+
"gpt-oss": {
|
|
137
|
+
name: "GPT-OSS",
|
|
138
138
|
limit: { output: 4000, context: 128000 },
|
|
139
139
|
modalities: {
|
|
140
|
-
input: [
|
|
141
|
-
output: [
|
|
140
|
+
input: ["text", "image"],
|
|
141
|
+
output: ["text"],
|
|
142
142
|
},
|
|
143
143
|
},
|
|
144
|
-
|
|
145
|
-
name:
|
|
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 (
|
|
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: [
|
|
170
|
+
ignore: ["node_modules", "dist", ".git", "coverage"],
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
|
-
catch (
|
|
173
|
+
catch (_a) {
|
|
174
174
|
// Config file doesn't exist, return default watcher config
|
|
175
|
-
return { ignore: [
|
|
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 (
|
|
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(
|
|
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(
|
|
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(),
|
|
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,
|
|
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,
|
|
71
|
+
const data = fs.readFileSync(this.configFilePath, "utf8");
|
|
72
72
|
this.defaultApiKey = JSON.parse(data);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
catch (
|
|
76
|
-
logger_1.logger.debug(
|
|
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 (
|
|
98
|
-
logger_1.logger.debug(
|
|
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(
|
|
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(
|
|
138
|
+
logger_1.logger.debug("Using existing default API key");
|
|
139
139
|
return this.defaultApiKey.key;
|
|
140
140
|
}
|
|
141
|
-
logger_1.logger.debug(
|
|
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(
|
|
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(
|
|
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(
|
|
159
|
-
errorMessage.includes(
|
|
160
|
-
errorMessage.includes(
|
|
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(
|
|
162
|
+
logger_1.logger.warn("Authentication required. Please run `berget auth login` first.");
|
|
163
163
|
}
|
|
164
164
|
else {
|
|
165
|
-
logger_1.logger.error(
|
|
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(
|
|
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(
|
|
186
|
-
rl.question(
|
|
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(
|
|
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:
|
|
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(
|
|
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(),
|
|
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,
|
|
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() +
|
|
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(),
|
|
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,
|
|
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 ===
|
|
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(
|
|
56
|
+
console.error(chalk_1.default.blue("\n💡 Troubleshooting tips:"));
|
|
57
57
|
// Authentication errors
|
|
58
|
-
if (errorType ===
|
|
59
|
-
errorCode ===
|
|
60
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
61
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
62
|
-
console.error(chalk_1.default.yellow(
|
|
63
|
-
console.error(chalk_1.default.white(
|
|
64
|
-
console.error(chalk_1.default.white(
|
|
65
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
69
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
70
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
71
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
72
|
-
console.error(chalk_1.default.yellow(
|
|
73
|
-
console.error(chalk_1.default.white(
|
|
74
|
-
console.error(chalk_1.default.white(
|
|
75
|
-
console.error(chalk_1.default.white(
|
|
76
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
80
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
81
|
-
errorType ===
|
|
82
|
-
console.error(chalk_1.default.yellow(
|
|
83
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
86
|
-
console.error(chalk_1.default.white(
|
|
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 ===
|
|
90
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
91
|
-
(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
92
|
-
console.error(chalk_1.default.yellow(
|
|
93
|
-
console.error(chalk_1.default.white(
|
|
94
|
-
console.error(chalk_1.default.white(
|
|
95
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
99
|
-
errorType ===
|
|
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(
|
|
102
|
-
console.error(chalk_1.default.white(
|
|
103
|
-
console.error(chalk_1.default.white(
|
|
104
|
-
console.error(chalk_1.default.white(
|
|
105
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
109
|
-
(
|
|
110
|
-
console.error(chalk_1.default.
|
|
111
|
-
console.error(chalk_1.default.white(
|
|
112
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
117
|
-
!(errorDetails === null || errorDetails === void 0 ? void 0 : errorDetails.includes(
|
|
118
|
-
!(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes(
|
|
119
|
-
!(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes(
|
|
120
|
-
!(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes(
|
|
121
|
-
!(errorCode === null || errorCode === void 0 ? void 0 : errorCode.includes(
|
|
122
|
-
console.error(chalk_1.default.yellow(
|
|
123
|
-
console.error(chalk_1.default.white(
|
|
124
|
-
console.error(chalk_1.default.white(
|
|
125
|
-
console.error(chalk_1.default.white(
|
|
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(
|
|
126
|
+
console.error(chalk_1.default.dim("\nNeed more help? Visit https://docs.berget.ai or contact support@berget.ai"));
|
|
128
127
|
}
|
package/dist/src/utils/logger.js
CHANGED
|
@@ -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(
|
|
29
|
+
else if (process.argv.includes("--debug")) {
|
|
30
30
|
this.logLevel = LogLevel.DEBUG;
|
|
31
31
|
}
|
|
32
|
-
else if (process.argv.includes(
|
|
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
|
|
47
|
+
case "none":
|
|
48
48
|
this.logLevel = LogLevel.NONE;
|
|
49
49
|
break;
|
|
50
|
-
case
|
|
50
|
+
case "error":
|
|
51
51
|
this.logLevel = LogLevel.ERROR;
|
|
52
52
|
break;
|
|
53
|
-
case
|
|
53
|
+
case "warn":
|
|
54
54
|
this.logLevel = LogLevel.WARN;
|
|
55
55
|
break;
|
|
56
|
-
case
|
|
56
|
+
case "info":
|
|
57
57
|
this.logLevel = LogLevel.INFO;
|
|
58
58
|
break;
|
|
59
|
-
case
|
|
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(
|
|
71
|
+
return markdownPatterns.some(pattern => pattern.test(text));
|
|
72
72
|
}
|
|
73
73
|
exports.containsMarkdown = containsMarkdown;
|