berget 2.1.0 ā 2.1.2
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/dist/package.json +1 -1
- package/dist/src/commands/code.js +37 -68
- package/dist/src/services/api-key-service.js +7 -4
- package/dist/src/services/auth-service.js +4 -2
- package/dist/src/services/registration-service.js +163 -0
- package/opencode.json +5 -1
- package/package.json +1 -1
- package/src/commands/code.ts +48 -115
- package/src/services/api-key-service.ts +6 -0
- package/src/services/auth-service.ts +5 -4
package/dist/package.json
CHANGED
|
@@ -357,9 +357,8 @@ function loadLatestAgentConfig() {
|
|
|
357
357
|
*/
|
|
358
358
|
function checkOpencodeInstalled() {
|
|
359
359
|
return new Promise((resolve) => {
|
|
360
|
-
const child = (0, child_process_1.spawn)('
|
|
360
|
+
const child = (0, child_process_1.spawn)('which', ['opencode'], {
|
|
361
361
|
stdio: 'pipe',
|
|
362
|
-
shell: true,
|
|
363
362
|
});
|
|
364
363
|
child.on('close', (code) => {
|
|
365
364
|
resolve(code === 0);
|
|
@@ -475,12 +474,9 @@ function registerCodeCommands(program) {
|
|
|
475
474
|
}
|
|
476
475
|
else {
|
|
477
476
|
// Only require authentication if we don't have an API key
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
yield authService.whoami();
|
|
482
|
-
}
|
|
483
|
-
catch (error) {
|
|
477
|
+
const authService = auth_service_1.AuthService.getInstance();
|
|
478
|
+
const profile = yield authService.whoami();
|
|
479
|
+
if (!profile) {
|
|
484
480
|
console.log(chalk_1.default.red('ā Not authenticated with Berget AI.'));
|
|
485
481
|
console.log(chalk_1.default.blue('To get started, you have two options:'));
|
|
486
482
|
console.log('');
|
|
@@ -504,62 +500,35 @@ function registerCodeCommands(program) {
|
|
|
504
500
|
let keyName;
|
|
505
501
|
try {
|
|
506
502
|
const apiKeyService = api_key_service_1.ApiKeyService.getInstance();
|
|
507
|
-
// Check for environment variable first (regardless of automation mode)
|
|
508
503
|
if (process.env.BERGET_API_KEY) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
else {
|
|
514
|
-
// List existing API keys
|
|
515
|
-
if (!options.yes) {
|
|
516
|
-
console.log(chalk_1.default.blue('\nš Checking existing API keys...'));
|
|
504
|
+
if (options.yes) {
|
|
505
|
+
console.log(chalk_1.default.blue('š Using BERGET_API_KEY from environment'));
|
|
506
|
+
apiKey = process.env.BERGET_API_KEY;
|
|
507
|
+
keyName = `env-key-${projectName}`;
|
|
517
508
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
console.log(chalk_1.default.blue('Found existing API keys:'));
|
|
509
|
+
else {
|
|
510
|
+
console.log(chalk_1.default.blue('\nš API key setup:'));
|
|
521
511
|
console.log(chalk_1.default.dim('ā'.repeat(60)));
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
console.log(chalk_1.default.dim(` Last used: ${key.lastUsed
|
|
526
|
-
? new Date(key.lastUsed).toLocaleDateString('sv-SE')
|
|
527
|
-
: 'Never'}`));
|
|
528
|
-
if (index < existingKeys.length - 1)
|
|
529
|
-
console.log();
|
|
530
|
-
});
|
|
512
|
+
console.log(`${chalk_1.default.cyan('1')} ${chalk_1.default.bold('Use existing API key')}`);
|
|
513
|
+
console.log(chalk_1.default.dim(' Uses BERGET_API_KEY from environment'));
|
|
514
|
+
console.log(`${chalk_1.default.cyan('2')} ${chalk_1.default.bold('Create a new API key')}`);
|
|
531
515
|
console.log(chalk_1.default.dim('ā'.repeat(60)));
|
|
532
|
-
console.log(chalk_1.default.cyan(`${existingKeys.length + 1}. Create a new API key`));
|
|
533
|
-
// Get user choice
|
|
534
516
|
const choice = yield new Promise((resolve) => {
|
|
535
517
|
const rl = readline_1.default.createInterface({
|
|
536
518
|
input: process.stdin,
|
|
537
519
|
output: process.stdout,
|
|
538
520
|
});
|
|
539
|
-
rl.question(chalk_1.default.blue('\nSelect an option (1-
|
|
521
|
+
rl.question(chalk_1.default.blue('\nSelect an option (1-2, default: 1): '), (answer) => {
|
|
540
522
|
rl.close();
|
|
541
|
-
resolve(answer.trim());
|
|
523
|
+
resolve(answer.trim() || '1');
|
|
542
524
|
});
|
|
543
525
|
});
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
keyName = selectedKey.name;
|
|
549
|
-
// We need to rotate the key to get the actual key value
|
|
550
|
-
console.log(chalk_1.default.yellow(`\nš Rotating API key "${selectedKey.name}" to get the key value...`));
|
|
551
|
-
if (yield confirm(chalk_1.default.yellow('This will invalidate the current key. Continue? (Y/n): '), options.yes)) {
|
|
552
|
-
const rotatedKey = yield apiKeyService.rotate(selectedKey.id.toString());
|
|
553
|
-
apiKey = rotatedKey.key;
|
|
554
|
-
console.log(chalk_1.default.green(`ā API key rotated successfully`));
|
|
555
|
-
}
|
|
556
|
-
else {
|
|
557
|
-
console.log(chalk_1.default.yellow('Cancelled. Please select a different option or create a new key.'));
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
526
|
+
if (choice === '1') {
|
|
527
|
+
console.log(chalk_1.default.blue('š Using BERGET_API_KEY from environment'));
|
|
528
|
+
apiKey = process.env.BERGET_API_KEY;
|
|
529
|
+
keyName = `env-key-${projectName}`;
|
|
560
530
|
}
|
|
561
|
-
else if (
|
|
562
|
-
// Create new key
|
|
531
|
+
else if (choice === '2') {
|
|
563
532
|
console.log(chalk_1.default.blue('\nš Creating new API key...'));
|
|
564
533
|
const defaultKeyName = `opencode-${projectName}-${Date.now()}`;
|
|
565
534
|
const customName = yield getInput(chalk_1.default.blue(`Enter key name (default: ${defaultKeyName}): `), defaultKeyName, options.yes);
|
|
@@ -574,20 +543,21 @@ function registerCodeCommands(program) {
|
|
|
574
543
|
return;
|
|
575
544
|
}
|
|
576
545
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
const customName = yield getInput(chalk_1.default.blue(`Enter key name (default: ${defaultKeyName}): `), defaultKeyName, options.yes);
|
|
585
|
-
keyName = customName;
|
|
586
|
-
const createOptions = { name: keyName };
|
|
587
|
-
const keyData = yield apiKeyService.create(createOptions);
|
|
588
|
-
apiKey = keyData.key;
|
|
589
|
-
console.log(chalk_1.default.green(`ā Created new API key: ${keyName}`));
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
if (!options.yes) {
|
|
549
|
+
console.log(chalk_1.default.yellow('No BERGET_API_KEY environment variable found.'));
|
|
550
|
+
console.log(chalk_1.default.blue('Creating a new API key...'));
|
|
551
|
+
console.log(chalk_1.default.dim('\nš” Tip: Set BERGET_API_KEY environment variable to reuse an existing key:'));
|
|
552
|
+
console.log(chalk_1.default.dim(' export BERGET_API_KEY=your_api_key_here'));
|
|
590
553
|
}
|
|
554
|
+
const defaultKeyName = `opencode-${projectName}-${Date.now()}`;
|
|
555
|
+
const customName = yield getInput(chalk_1.default.blue(`Enter key name (default: ${defaultKeyName}): `), defaultKeyName, options.yes);
|
|
556
|
+
keyName = customName;
|
|
557
|
+
const createOptions = { name: keyName };
|
|
558
|
+
const keyData = yield apiKeyService.create(createOptions);
|
|
559
|
+
apiKey = keyData.key;
|
|
560
|
+
console.log(chalk_1.default.green(`ā Created new API key: ${keyName}`));
|
|
591
561
|
}
|
|
592
562
|
}
|
|
593
563
|
catch (error) {
|
|
@@ -747,12 +717,13 @@ function registerCodeCommands(program) {
|
|
|
747
717
|
models: {
|
|
748
718
|
'glm-4.7': {
|
|
749
719
|
name: 'GLM-4.7',
|
|
750
|
-
limit: { output: 4000, context:
|
|
720
|
+
limit: { output: 4000, context: 200000 },
|
|
721
|
+
modalities: { input: ['text'], output: ['text'] },
|
|
751
722
|
},
|
|
752
723
|
'gpt-oss': {
|
|
753
724
|
name: 'GPT-OSS',
|
|
754
725
|
limit: { output: 4000, context: 128000 },
|
|
755
|
-
modalities: ['text', 'image'],
|
|
726
|
+
modalities: { input: ['text', 'image'], output: ['text'] },
|
|
756
727
|
},
|
|
757
728
|
'llama-8b': {
|
|
758
729
|
name: 'llama-3.1-8b',
|
|
@@ -1050,7 +1021,6 @@ All agents follow these principles:
|
|
|
1050
1021
|
const opencode = (0, child_process_1.spawn)('opencode', opencodeArgs, {
|
|
1051
1022
|
stdio: 'inherit',
|
|
1052
1023
|
env: env,
|
|
1053
|
-
shell: true,
|
|
1054
1024
|
});
|
|
1055
1025
|
opencode.on('close', (code) => {
|
|
1056
1026
|
if (code !== 0) {
|
|
@@ -1090,7 +1060,6 @@ All agents follow these principles:
|
|
|
1090
1060
|
// Spawn opencode serve process
|
|
1091
1061
|
const opencode = (0, child_process_1.spawn)('opencode', serveArgs, {
|
|
1092
1062
|
stdio: 'inherit',
|
|
1093
|
-
shell: true,
|
|
1094
1063
|
});
|
|
1095
1064
|
opencode.on('close', (code) => {
|
|
1096
1065
|
if (code !== 0) {
|
|
@@ -50,7 +50,7 @@ class ApiKeyService {
|
|
|
50
50
|
* Command: berget api-keys create
|
|
51
51
|
*/
|
|
52
52
|
create(options) {
|
|
53
|
-
var _a, _b, _c, _d;
|
|
53
|
+
var _a, _b, _c, _d, _e;
|
|
54
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
55
|
try {
|
|
56
56
|
// Validate input before sending request
|
|
@@ -89,13 +89,16 @@ class ApiKeyService {
|
|
|
89
89
|
detailedMessage += '5. Contact support if the problem persists';
|
|
90
90
|
throw new Error(detailedMessage);
|
|
91
91
|
}
|
|
92
|
-
if (((_b = errorObj.error) === null || _b === void 0 ? void 0 : _b.code) === '
|
|
92
|
+
if (((_b = errorObj.error) === null || _b === void 0 ? void 0 : _b.code) === 'USER_NOT_FOUND') {
|
|
93
|
+
throw new Error('Your account is still being set up. Please wait a moment and try again.\n\nIf this issue persists, please contact support at support@berget.ai');
|
|
94
|
+
}
|
|
95
|
+
if (((_c = errorObj.error) === null || _c === void 0 ? void 0 : _c.code) === 'QUOTA_EXCEEDED') {
|
|
93
96
|
throw new Error('You have reached your API key limit. Please delete existing keys or contact support to increase your quota.');
|
|
94
97
|
}
|
|
95
|
-
if (((
|
|
98
|
+
if (((_d = errorObj.error) === null || _d === void 0 ? void 0 : _d.code) === 'INSUFFICIENT_PERMISSIONS') {
|
|
96
99
|
throw new Error('Your account does not have permission to create API keys. Please contact your administrator.');
|
|
97
100
|
}
|
|
98
|
-
if (((
|
|
101
|
+
if (((_e = errorObj.error) === null || _e === void 0 ? void 0 : _e.code) === 'BILLING_REQUIRED') {
|
|
99
102
|
throw new Error('A valid billing method is required to create API keys. Please add a payment method.');
|
|
100
103
|
}
|
|
101
104
|
}
|
|
@@ -60,12 +60,11 @@ class AuthService {
|
|
|
60
60
|
try {
|
|
61
61
|
const { data: profile, error } = yield this.client.GET('/v1/users/me');
|
|
62
62
|
if (error) {
|
|
63
|
-
|
|
63
|
+
return null;
|
|
64
64
|
}
|
|
65
65
|
return profile;
|
|
66
66
|
}
|
|
67
67
|
catch (error) {
|
|
68
|
-
(0, error_handler_1.handleError)('Failed to get user profile', error);
|
|
69
68
|
return null;
|
|
70
69
|
}
|
|
71
70
|
});
|
|
@@ -187,6 +186,9 @@ class AuthService {
|
|
|
187
186
|
const user = typedTokenData.user;
|
|
188
187
|
console.log(chalk_1.default.green(`Logged in as ${user.name || user.email || 'User'}`));
|
|
189
188
|
}
|
|
189
|
+
console.log(chalk_1.default.cyan('\nNext steps:'));
|
|
190
|
+
console.log(chalk_1.default.cyan(' ⢠Create an API key: berget api-keys create'));
|
|
191
|
+
console.log(chalk_1.default.cyan(' ⢠Setup OpenCode: berget code init'));
|
|
190
192
|
return true;
|
|
191
193
|
}
|
|
192
194
|
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.RegistrationService = void 0;
|
|
39
|
+
const client_1 = require("../client");
|
|
40
|
+
const error_handler_1 = require("../utils/error-handler");
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const readline = __importStar(require("readline"));
|
|
43
|
+
/**
|
|
44
|
+
* Service for handling user registration and account completion
|
|
45
|
+
*/
|
|
46
|
+
class RegistrationService {
|
|
47
|
+
constructor() {
|
|
48
|
+
this.client = (0, client_1.createAuthenticatedClient)();
|
|
49
|
+
}
|
|
50
|
+
static getInstance() {
|
|
51
|
+
if (!RegistrationService.instance) {
|
|
52
|
+
RegistrationService.instance = new RegistrationService();
|
|
53
|
+
}
|
|
54
|
+
return RegistrationService.instance;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check authentication status to see if user has completed registration
|
|
58
|
+
*/
|
|
59
|
+
checkAuthStatus() {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
try {
|
|
62
|
+
const { data, error } = yield this.client.GET('/v1/auth/status');
|
|
63
|
+
if (error)
|
|
64
|
+
throw error;
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
(0, error_handler_1.handleError)('Failed to check authentication status', error);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Complete registration for a new user
|
|
75
|
+
*/
|
|
76
|
+
completeRegistration(request) {
|
|
77
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
try {
|
|
79
|
+
const { data, error } = yield this.client.POST('/v1/users/me/complete-registration', {
|
|
80
|
+
body: request,
|
|
81
|
+
});
|
|
82
|
+
if (error) {
|
|
83
|
+
throw new Error(JSON.stringify(error));
|
|
84
|
+
}
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
console.error('Failed to complete registration:', error);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if registration is needed based on auth status
|
|
95
|
+
*/
|
|
96
|
+
isRegistrationNeeded() {
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
try {
|
|
99
|
+
const status = yield this.checkAuthStatus();
|
|
100
|
+
return !status.hasOdooAccount;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Prompt user for registration information
|
|
109
|
+
*/
|
|
110
|
+
collectRegistrationInfo() {
|
|
111
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
+
const rl = readline.createInterface({
|
|
113
|
+
input: process.stdin,
|
|
114
|
+
output: process.stdout,
|
|
115
|
+
});
|
|
116
|
+
const question = (prompt) => {
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
rl.question(prompt, (answer) => {
|
|
119
|
+
resolve(answer.trim());
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
console.log(chalk_1.default.cyan('\nš Complete your registration\n'));
|
|
124
|
+
console.log(chalk_1.default.dim('ā'.repeat(50)));
|
|
125
|
+
const companyName = yield question(chalk_1.default.blue('Company name: '));
|
|
126
|
+
const companyEmail = yield question(chalk_1.default.blue('Company email: '));
|
|
127
|
+
const vatNumber = yield question(chalk_1.default.blue('VAT number (optional): '));
|
|
128
|
+
console.log(chalk_1.default.cyan('\nš Plan Selection'));
|
|
129
|
+
console.log(chalk_1.default.dim('ā'.repeat(50)));
|
|
130
|
+
console.log(chalk_1.default.yellow('You will start with a trial plan (ID: 142). To add a credit card,'));
|
|
131
|
+
console.log(chalk_1.default.yellow('please visit https://console.berget.ai\n'));
|
|
132
|
+
const marketingConsent = yield question(chalk_1.default.blue('Subscribe to marketing emails? (Y/n): '));
|
|
133
|
+
console.log(chalk_1.default.cyan('\nš Terms of Service'));
|
|
134
|
+
console.log(chalk_1.default.dim('ā'.repeat(50)));
|
|
135
|
+
console.log(chalk_1.default.cyan('Please review our terms:'));
|
|
136
|
+
console.log(chalk_1.default.dim(' ⢠https://berget.ai/terms'));
|
|
137
|
+
console.log(chalk_1.default.dim(' ⢠https://berget.ai/acceptable-use'));
|
|
138
|
+
console.log(chalk_1.default.dim(' ⢠https://berget.ai/dpa\n'));
|
|
139
|
+
const termsAccepted = yield question(chalk_1.default.blue('Do you accept the terms? (Y/n): '));
|
|
140
|
+
rl.close();
|
|
141
|
+
return {
|
|
142
|
+
company: {
|
|
143
|
+
name: companyName,
|
|
144
|
+
email: companyEmail,
|
|
145
|
+
vatNumber: vatNumber || '',
|
|
146
|
+
},
|
|
147
|
+
plans: [
|
|
148
|
+
{
|
|
149
|
+
id: '142',
|
|
150
|
+
quantity: 1,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
paymentMethodId: '',
|
|
154
|
+
stripeCustomerId: '',
|
|
155
|
+
marketingConsent: marketingConsent.toLowerCase() !== 'n' &&
|
|
156
|
+
marketingConsent.toLowerCase() !== 'no',
|
|
157
|
+
termsAccepted: termsAccepted.toLowerCase() !== 'n' &&
|
|
158
|
+
termsAccepted.toLowerCase() !== 'no',
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.RegistrationService = RegistrationService;
|
package/opencode.json
CHANGED
package/package.json
CHANGED
package/src/commands/code.ts
CHANGED
|
@@ -376,9 +376,8 @@ async function loadLatestAgentConfig(): Promise<any> {
|
|
|
376
376
|
*/
|
|
377
377
|
function checkOpencodeInstalled(): Promise<boolean> {
|
|
378
378
|
return new Promise((resolve) => {
|
|
379
|
-
const child = spawn('
|
|
379
|
+
const child = spawn('which', ['opencode'], {
|
|
380
380
|
stdio: 'pipe',
|
|
381
|
-
shell: true,
|
|
382
381
|
})
|
|
383
382
|
|
|
384
383
|
child.on('close', (code) => {
|
|
@@ -530,11 +529,10 @@ export function registerCodeCommands(program: Command): void {
|
|
|
530
529
|
)
|
|
531
530
|
} else {
|
|
532
531
|
// Only require authentication if we don't have an API key
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
} catch (error) {
|
|
532
|
+
const authService = AuthService.getInstance()
|
|
533
|
+
const profile = await authService.whoami()
|
|
534
|
+
|
|
535
|
+
if (!profile) {
|
|
538
536
|
console.log(chalk.red('ā Not authenticated with Berget AI.'))
|
|
539
537
|
console.log(chalk.blue('To get started, you have two options:'))
|
|
540
538
|
console.log('')
|
|
@@ -578,104 +576,39 @@ export function registerCodeCommands(program: Command): void {
|
|
|
578
576
|
try {
|
|
579
577
|
const apiKeyService = ApiKeyService.getInstance()
|
|
580
578
|
|
|
581
|
-
// Check for environment variable first (regardless of automation mode)
|
|
582
579
|
if (process.env.BERGET_API_KEY) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
console.log(chalk.blue('\nš Checking existing API keys...'))
|
|
590
|
-
}
|
|
591
|
-
const existingKeys = await apiKeyService.list()
|
|
592
|
-
|
|
593
|
-
if (existingKeys.length > 0 && !options.yes) {
|
|
594
|
-
console.log(chalk.blue('Found existing API keys:'))
|
|
595
|
-
console.log(chalk.dim('ā'.repeat(60)))
|
|
596
|
-
existingKeys.forEach((key, index) => {
|
|
597
|
-
console.log(
|
|
598
|
-
`${chalk.cyan((index + 1).toString())}. ${chalk.bold(
|
|
599
|
-
key.name
|
|
600
|
-
)} (${key.prefix}...)`
|
|
601
|
-
)
|
|
602
|
-
console.log(
|
|
603
|
-
chalk.dim(
|
|
604
|
-
` Created: ${new Date(key.created).toLocaleDateString(
|
|
605
|
-
'sv-SE'
|
|
606
|
-
)}`
|
|
607
|
-
)
|
|
608
|
-
)
|
|
609
|
-
console.log(
|
|
610
|
-
chalk.dim(
|
|
611
|
-
` Last used: ${
|
|
612
|
-
key.lastUsed
|
|
613
|
-
? new Date(key.lastUsed).toLocaleDateString('sv-SE')
|
|
614
|
-
: 'Never'
|
|
615
|
-
}`
|
|
616
|
-
)
|
|
617
|
-
)
|
|
618
|
-
if (index < existingKeys.length - 1) console.log()
|
|
619
|
-
})
|
|
580
|
+
if (options.yes) {
|
|
581
|
+
console.log(chalk.blue('š Using BERGET_API_KEY from environment'))
|
|
582
|
+
apiKey = process.env.BERGET_API_KEY
|
|
583
|
+
keyName = `env-key-${projectName}`
|
|
584
|
+
} else {
|
|
585
|
+
console.log(chalk.blue('\nš API key setup:'))
|
|
620
586
|
console.log(chalk.dim('ā'.repeat(60)))
|
|
621
587
|
console.log(
|
|
622
|
-
chalk.cyan(
|
|
588
|
+
`${chalk.cyan('1')} ${chalk.bold('Use existing API key')}`
|
|
589
|
+
)
|
|
590
|
+
console.log(chalk.dim(' Uses BERGET_API_KEY from environment'))
|
|
591
|
+
console.log(
|
|
592
|
+
`${chalk.cyan('2')} ${chalk.bold('Create a new API key')}`
|
|
623
593
|
)
|
|
594
|
+
console.log(chalk.dim('ā'.repeat(60)))
|
|
624
595
|
|
|
625
|
-
// Get user choice
|
|
626
596
|
const choice = await new Promise<string>((resolve) => {
|
|
627
597
|
const rl = readline.createInterface({
|
|
628
598
|
input: process.stdin,
|
|
629
599
|
output: process.stdout,
|
|
630
600
|
})
|
|
631
|
-
rl.question(
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
(answer) => {
|
|
636
|
-
rl.close()
|
|
637
|
-
resolve(answer.trim())
|
|
638
|
-
}
|
|
639
|
-
)
|
|
601
|
+
rl.question(chalk.blue('\nSelect an option (1-2, default: 1): '), (answer) => {
|
|
602
|
+
rl.close()
|
|
603
|
+
resolve(answer.trim() || '1')
|
|
604
|
+
})
|
|
640
605
|
})
|
|
641
606
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
keyName = selectedKey.name
|
|
648
|
-
|
|
649
|
-
// We need to rotate the key to get the actual key value
|
|
650
|
-
console.log(
|
|
651
|
-
chalk.yellow(
|
|
652
|
-
`\nš Rotating API key "${selectedKey.name}" to get the key value...`
|
|
653
|
-
)
|
|
654
|
-
)
|
|
655
|
-
|
|
656
|
-
if (
|
|
657
|
-
await confirm(
|
|
658
|
-
chalk.yellow(
|
|
659
|
-
'This will invalidate the current key. Continue? (Y/n): '
|
|
660
|
-
),
|
|
661
|
-
options.yes
|
|
662
|
-
)
|
|
663
|
-
) {
|
|
664
|
-
const rotatedKey = await apiKeyService.rotate(
|
|
665
|
-
selectedKey.id.toString()
|
|
666
|
-
)
|
|
667
|
-
apiKey = rotatedKey.key
|
|
668
|
-
console.log(chalk.green(`ā API key rotated successfully`))
|
|
669
|
-
} else {
|
|
670
|
-
console.log(
|
|
671
|
-
chalk.yellow(
|
|
672
|
-
'Cancelled. Please select a different option or create a new key.'
|
|
673
|
-
)
|
|
674
|
-
)
|
|
675
|
-
return
|
|
676
|
-
}
|
|
677
|
-
} else if (choiceIndex === existingKeys.length) {
|
|
678
|
-
// Create new key
|
|
607
|
+
if (choice === '1') {
|
|
608
|
+
console.log(chalk.blue('š Using BERGET_API_KEY from environment'))
|
|
609
|
+
apiKey = process.env.BERGET_API_KEY
|
|
610
|
+
keyName = `env-key-${projectName}`
|
|
611
|
+
} else if (choice === '2') {
|
|
679
612
|
console.log(chalk.blue('\nš Creating new API key...'))
|
|
680
613
|
|
|
681
614
|
const defaultKeyName = `opencode-${projectName}-${Date.now()}`
|
|
@@ -694,26 +627,27 @@ export function registerCodeCommands(program: Command): void {
|
|
|
694
627
|
console.log(chalk.red('Invalid selection.'))
|
|
695
628
|
return
|
|
696
629
|
}
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
630
|
+
}
|
|
631
|
+
} else {
|
|
632
|
+
if (!options.yes) {
|
|
633
|
+
console.log(chalk.yellow('No BERGET_API_KEY environment variable found.'))
|
|
634
|
+
console.log(chalk.blue('Creating a new API key...'))
|
|
635
|
+
console.log(chalk.dim('\nš” Tip: Set BERGET_API_KEY environment variable to reuse an existing key:'))
|
|
636
|
+
console.log(chalk.dim(' export BERGET_API_KEY=your_api_key_here'))
|
|
637
|
+
}
|
|
703
638
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
639
|
+
const defaultKeyName = `opencode-${projectName}-${Date.now()}`
|
|
640
|
+
const customName = await getInput(
|
|
641
|
+
chalk.blue(`Enter key name (default: ${defaultKeyName}): `),
|
|
642
|
+
defaultKeyName,
|
|
643
|
+
options.yes
|
|
644
|
+
)
|
|
710
645
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
}
|
|
646
|
+
keyName = customName
|
|
647
|
+
const createOptions: CreateApiKeyOptions = { name: keyName }
|
|
648
|
+
const keyData = await apiKeyService.create(createOptions)
|
|
649
|
+
apiKey = keyData.key
|
|
650
|
+
console.log(chalk.green(`ā Created new API key: ${keyName}`))
|
|
717
651
|
}
|
|
718
652
|
} catch (error) {
|
|
719
653
|
if (process.env.BERGET_API_KEY) {
|
|
@@ -901,12 +835,13 @@ export function registerCodeCommands(program: Command): void {
|
|
|
901
835
|
models: {
|
|
902
836
|
'glm-4.7': {
|
|
903
837
|
name: 'GLM-4.7',
|
|
904
|
-
limit: { output: 4000, context:
|
|
838
|
+
limit: { output: 4000, context: 200000 },
|
|
839
|
+
modalities: { input: ['text'], output: ['text'] },
|
|
905
840
|
},
|
|
906
841
|
'gpt-oss': {
|
|
907
842
|
name: 'GPT-OSS',
|
|
908
843
|
limit: { output: 4000, context: 128000 },
|
|
909
|
-
modalities: ['text', 'image'],
|
|
844
|
+
modalities: { input: ['text', 'image'], output: ['text'] },
|
|
910
845
|
},
|
|
911
846
|
'llama-8b': {
|
|
912
847
|
name: 'llama-3.1-8b',
|
|
@@ -1269,7 +1204,6 @@ All agents follow these principles:
|
|
|
1269
1204
|
const opencode = spawn('opencode', opencodeArgs, {
|
|
1270
1205
|
stdio: 'inherit',
|
|
1271
1206
|
env: env,
|
|
1272
|
-
shell: true,
|
|
1273
1207
|
})
|
|
1274
1208
|
|
|
1275
1209
|
opencode.on('close', (code) => {
|
|
@@ -1322,7 +1256,6 @@ All agents follow these principles:
|
|
|
1322
1256
|
// Spawn opencode serve process
|
|
1323
1257
|
const opencode = spawn('opencode', serveArgs, {
|
|
1324
1258
|
stdio: 'inherit',
|
|
1325
|
-
shell: true,
|
|
1326
1259
|
})
|
|
1327
1260
|
|
|
1328
1261
|
opencode.on('close', (code) => {
|
|
@@ -115,6 +115,12 @@ export class ApiKeyService {
|
|
|
115
115
|
throw new Error(detailedMessage)
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
if (errorObj.error?.code === 'USER_NOT_FOUND') {
|
|
119
|
+
throw new Error(
|
|
120
|
+
'Your account is still being set up. Please wait a moment and try again.\n\nIf this issue persists, please contact support at support@berget.ai',
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
|
|
118
124
|
if (errorObj.error?.code === 'QUOTA_EXCEEDED') {
|
|
119
125
|
throw new Error(
|
|
120
126
|
'You have reached your API key limit. Please delete existing keys or contact support to increase your quota.',
|
|
@@ -36,13 +36,10 @@ export class AuthService {
|
|
|
36
36
|
try {
|
|
37
37
|
const { data: profile, error } = await this.client.GET('/v1/users/me')
|
|
38
38
|
if (error) {
|
|
39
|
-
|
|
40
|
-
error ? JSON.stringify(error) : 'Failed to get user profile',
|
|
41
|
-
)
|
|
39
|
+
return null
|
|
42
40
|
}
|
|
43
41
|
return profile
|
|
44
42
|
} catch (error) {
|
|
45
|
-
handleError('Failed to get user profile', error)
|
|
46
43
|
return null
|
|
47
44
|
}
|
|
48
45
|
}
|
|
@@ -250,6 +247,10 @@ export class AuthService {
|
|
|
250
247
|
)
|
|
251
248
|
}
|
|
252
249
|
|
|
250
|
+
console.log(chalk.cyan('\nNext steps:'))
|
|
251
|
+
console.log(chalk.cyan(' ⢠Create an API key: berget api-keys create'))
|
|
252
|
+
console.log(chalk.cyan(' ⢠Setup OpenCode: berget code init'))
|
|
253
|
+
|
|
253
254
|
return true
|
|
254
255
|
}
|
|
255
256
|
}
|