berget 0.1.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +92 -0
  2. package/dist/index.js +7 -439
  3. package/dist/src/client.js +193 -102
  4. package/dist/src/commands/api-keys.js +271 -0
  5. package/dist/src/commands/auth.js +65 -0
  6. package/dist/src/commands/autocomplete.js +24 -0
  7. package/dist/src/commands/billing.js +53 -0
  8. package/dist/src/commands/chat.js +276 -0
  9. package/dist/src/commands/clusters.js +69 -0
  10. package/dist/src/commands/index.js +25 -0
  11. package/dist/src/commands/models.js +69 -0
  12. package/dist/src/commands/users.js +43 -0
  13. package/dist/src/constants/command-structure.js +164 -0
  14. package/dist/src/services/api-key-service.js +34 -5
  15. package/dist/src/services/auth-service.js +83 -43
  16. package/dist/src/services/chat-service.js +177 -0
  17. package/dist/src/services/cluster-service.js +37 -2
  18. package/dist/src/services/collaborator-service.js +21 -4
  19. package/dist/src/services/flux-service.js +21 -4
  20. package/dist/src/services/helm-service.js +20 -3
  21. package/dist/src/services/kubectl-service.js +26 -5
  22. package/dist/src/utils/config-checker.js +50 -0
  23. package/dist/src/utils/default-api-key.js +111 -0
  24. package/dist/src/utils/token-manager.js +165 -0
  25. package/index.ts +5 -529
  26. package/package.json +6 -1
  27. package/src/client.ts +262 -80
  28. package/src/commands/api-keys.ts +364 -0
  29. package/src/commands/auth.ts +58 -0
  30. package/src/commands/autocomplete.ts +19 -0
  31. package/src/commands/billing.ts +41 -0
  32. package/src/commands/chat.ts +345 -0
  33. package/src/commands/clusters.ts +65 -0
  34. package/src/commands/index.ts +23 -0
  35. package/src/commands/models.ts +63 -0
  36. package/src/commands/users.ts +37 -0
  37. package/src/constants/command-structure.ts +184 -0
  38. package/src/services/api-key-service.ts +36 -5
  39. package/src/services/auth-service.ts +101 -44
  40. package/src/services/chat-service.ts +177 -0
  41. package/src/services/cluster-service.ts +37 -2
  42. package/src/services/collaborator-service.ts +23 -4
  43. package/src/services/flux-service.ts +23 -4
  44. package/src/services/helm-service.ts +22 -3
  45. package/src/services/kubectl-service.ts +28 -5
  46. package/src/types/api.d.ts +58 -192
  47. package/src/utils/config-checker.ts +23 -0
  48. package/src/utils/default-api-key.ts +94 -0
  49. package/src/utils/token-manager.ts +150 -0
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /**
3
+ * Command structure constants for the CLI
4
+ * Following patterns from AWS CLI and Google Cloud CLI
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.COMMAND_DESCRIPTIONS = exports.SUBCOMMANDS = exports.COMMAND_GROUPS = void 0;
8
+ // Main command groups
9
+ exports.COMMAND_GROUPS = {
10
+ AUTH: 'auth',
11
+ API_KEYS: 'api-keys',
12
+ CLUSTERS: 'clusters',
13
+ APPS: 'apps',
14
+ MODELS: 'models',
15
+ HELM: 'helm',
16
+ KUBECTL: 'kubectl',
17
+ FLUX: 'flux',
18
+ USERS: 'users',
19
+ BILLING: 'billing',
20
+ CHAT: 'chat',
21
+ };
22
+ // Subcommands for each group
23
+ exports.SUBCOMMANDS = {
24
+ // Auth commands
25
+ AUTH: {
26
+ LOGIN: 'login',
27
+ LOGOUT: 'logout',
28
+ WHOAMI: 'whoami',
29
+ },
30
+ // Chat commands
31
+ CHAT: {
32
+ RUN: 'run',
33
+ LIST: 'list',
34
+ },
35
+ // API Keys commands
36
+ API_KEYS: {
37
+ LIST: 'list',
38
+ CREATE: 'create',
39
+ DELETE: 'delete',
40
+ ROTATE: 'rotate',
41
+ DESCRIBE: 'describe',
42
+ SET_DEFAULT: 'set-default',
43
+ GET_DEFAULT: 'get-default',
44
+ },
45
+ // Clusters commands
46
+ CLUSTERS: {
47
+ LIST: 'list',
48
+ DESCRIBE: 'describe',
49
+ GET_USAGE: 'get-usage',
50
+ },
51
+ // Apps commands
52
+ APPS: {
53
+ LIST_TEMPLATES: 'list-templates',
54
+ DESCRIBE_TEMPLATE: 'describe-template',
55
+ LIST_INSTALLATIONS: 'list-installations',
56
+ INSTALL: 'install',
57
+ UNINSTALL: 'uninstall',
58
+ DESCRIBE_INSTALLATION: 'describe-installation',
59
+ },
60
+ // Models commands
61
+ MODELS: {
62
+ LIST: 'list',
63
+ DESCRIBE: 'describe',
64
+ },
65
+ // Helm commands
66
+ HELM: {
67
+ ADD_REPO: 'add-repo',
68
+ INSTALL: 'install',
69
+ },
70
+ // Kubectl commands
71
+ KUBECTL: {
72
+ CREATE_NAMESPACE: 'create-namespace',
73
+ APPLY: 'apply',
74
+ GET: 'get',
75
+ },
76
+ // Flux commands
77
+ FLUX: {
78
+ INSTALL: 'install',
79
+ BOOTSTRAP: 'bootstrap',
80
+ },
81
+ // Users commands
82
+ USERS: {
83
+ LIST: 'list',
84
+ DESCRIBE: 'describe',
85
+ UPDATE: 'update',
86
+ INVITE: 'invite',
87
+ },
88
+ // Billing commands
89
+ BILLING: {
90
+ GET_USAGE: 'get-usage',
91
+ LIST_INVOICES: 'list-invoices',
92
+ DESCRIBE_INVOICE: 'describe-invoice',
93
+ LIST_PAYMENT_METHODS: 'list-payment-methods',
94
+ ADD_PAYMENT_METHOD: 'add-payment-method',
95
+ REMOVE_PAYMENT_METHOD: 'remove-payment-method',
96
+ UPDATE_SUBSCRIPTION: 'update-subscription',
97
+ },
98
+ };
99
+ // Command descriptions
100
+ exports.COMMAND_DESCRIPTIONS = {
101
+ // Auth group
102
+ [exports.COMMAND_GROUPS.AUTH]: 'Manage authentication and authorization',
103
+ [`${exports.COMMAND_GROUPS.AUTH} ${exports.SUBCOMMANDS.AUTH.LOGIN}`]: 'Log in to Berget AI',
104
+ [`${exports.COMMAND_GROUPS.AUTH} ${exports.SUBCOMMANDS.AUTH.LOGOUT}`]: 'Log out from Berget AI',
105
+ [`${exports.COMMAND_GROUPS.AUTH} ${exports.SUBCOMMANDS.AUTH.WHOAMI}`]: 'Display current user information',
106
+ // API Keys group
107
+ [exports.COMMAND_GROUPS.API_KEYS]: 'Manage API keys',
108
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.LIST}`]: 'List all API keys',
109
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.CREATE}`]: 'Create a new API key',
110
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.DELETE}`]: 'Delete an API key',
111
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.ROTATE}`]: 'Rotate an API key',
112
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.DESCRIBE}`]: 'Get usage statistics for an API key',
113
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.SET_DEFAULT}`]: 'Set an API key as the default for chat commands',
114
+ [`${exports.COMMAND_GROUPS.API_KEYS} ${exports.SUBCOMMANDS.API_KEYS.GET_DEFAULT}`]: 'Show the current default API key',
115
+ // Clusters group
116
+ [exports.COMMAND_GROUPS.CLUSTERS]: 'Manage Kubernetes clusters',
117
+ [`${exports.COMMAND_GROUPS.CLUSTERS} ${exports.SUBCOMMANDS.CLUSTERS.LIST}`]: 'List all clusters',
118
+ [`${exports.COMMAND_GROUPS.CLUSTERS} ${exports.SUBCOMMANDS.CLUSTERS.DESCRIBE}`]: 'Get detailed information about a cluster',
119
+ [`${exports.COMMAND_GROUPS.CLUSTERS} ${exports.SUBCOMMANDS.CLUSTERS.GET_USAGE}`]: 'Get resource usage for a cluster',
120
+ // Apps group
121
+ [exports.COMMAND_GROUPS.APPS]: 'Manage applications',
122
+ [`${exports.COMMAND_GROUPS.APPS} ${exports.SUBCOMMANDS.APPS.LIST_TEMPLATES}`]: 'List available application templates',
123
+ [`${exports.COMMAND_GROUPS.APPS} ${exports.SUBCOMMANDS.APPS.DESCRIBE_TEMPLATE}`]: 'Get detailed information about an application template',
124
+ [`${exports.COMMAND_GROUPS.APPS} ${exports.SUBCOMMANDS.APPS.LIST_INSTALLATIONS}`]: 'List installed applications',
125
+ [`${exports.COMMAND_GROUPS.APPS} ${exports.SUBCOMMANDS.APPS.INSTALL}`]: 'Install an application',
126
+ [`${exports.COMMAND_GROUPS.APPS} ${exports.SUBCOMMANDS.APPS.UNINSTALL}`]: 'Uninstall an application',
127
+ [`${exports.COMMAND_GROUPS.APPS} ${exports.SUBCOMMANDS.APPS.DESCRIBE_INSTALLATION}`]: 'Get detailed information about an installed application',
128
+ // Models group
129
+ [exports.COMMAND_GROUPS.MODELS]: 'Manage AI models',
130
+ [`${exports.COMMAND_GROUPS.MODELS} ${exports.SUBCOMMANDS.MODELS.LIST}`]: 'List available AI models',
131
+ [`${exports.COMMAND_GROUPS.MODELS} ${exports.SUBCOMMANDS.MODELS.DESCRIBE}`]: 'Get detailed information about an AI model',
132
+ // Helm group
133
+ [exports.COMMAND_GROUPS.HELM]: 'Manage Helm charts',
134
+ [`${exports.COMMAND_GROUPS.HELM} ${exports.SUBCOMMANDS.HELM.ADD_REPO}`]: 'Add a Helm repository',
135
+ [`${exports.COMMAND_GROUPS.HELM} ${exports.SUBCOMMANDS.HELM.INSTALL}`]: 'Install a Helm chart',
136
+ // Kubectl group
137
+ [exports.COMMAND_GROUPS.KUBECTL]: 'Manage Kubernetes resources',
138
+ [`${exports.COMMAND_GROUPS.KUBECTL} ${exports.SUBCOMMANDS.KUBECTL.CREATE_NAMESPACE}`]: 'Create a Kubernetes namespace',
139
+ [`${exports.COMMAND_GROUPS.KUBECTL} ${exports.SUBCOMMANDS.KUBECTL.APPLY}`]: 'Apply a Kubernetes configuration',
140
+ [`${exports.COMMAND_GROUPS.KUBECTL} ${exports.SUBCOMMANDS.KUBECTL.GET}`]: 'Get Kubernetes resources',
141
+ // Flux group
142
+ [exports.COMMAND_GROUPS.FLUX]: 'Manage Flux CD',
143
+ [`${exports.COMMAND_GROUPS.FLUX} ${exports.SUBCOMMANDS.FLUX.INSTALL}`]: 'Install Flux CD',
144
+ [`${exports.COMMAND_GROUPS.FLUX} ${exports.SUBCOMMANDS.FLUX.BOOTSTRAP}`]: 'Bootstrap Flux CD',
145
+ // Users group
146
+ [exports.COMMAND_GROUPS.USERS]: 'Manage users',
147
+ [`${exports.COMMAND_GROUPS.USERS} ${exports.SUBCOMMANDS.USERS.LIST}`]: 'List all users in your organization',
148
+ [`${exports.COMMAND_GROUPS.USERS} ${exports.SUBCOMMANDS.USERS.DESCRIBE}`]: 'Get detailed information about a user',
149
+ [`${exports.COMMAND_GROUPS.USERS} ${exports.SUBCOMMANDS.USERS.UPDATE}`]: 'Update user information',
150
+ [`${exports.COMMAND_GROUPS.USERS} ${exports.SUBCOMMANDS.USERS.INVITE}`]: 'Invite a new user to your organization',
151
+ // Billing group
152
+ [exports.COMMAND_GROUPS.BILLING]: 'Manage billing and usage',
153
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.GET_USAGE}`]: 'Get current usage metrics',
154
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.LIST_INVOICES}`]: 'List all invoices',
155
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.DESCRIBE_INVOICE}`]: 'Get detailed information about an invoice',
156
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.LIST_PAYMENT_METHODS}`]: 'List all payment methods',
157
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.ADD_PAYMENT_METHOD}`]: 'Add a new payment method',
158
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.REMOVE_PAYMENT_METHOD}`]: 'Remove a payment method',
159
+ [`${exports.COMMAND_GROUPS.BILLING} ${exports.SUBCOMMANDS.BILLING.UPDATE_SUBSCRIPTION}`]: 'Update subscription plan',
160
+ // Chat group
161
+ [exports.COMMAND_GROUPS.CHAT]: 'Interact with AI chat models',
162
+ [`${exports.COMMAND_GROUPS.CHAT} ${exports.SUBCOMMANDS.CHAT.RUN}`]: 'Run a chat session with a specified model',
163
+ [`${exports.COMMAND_GROUPS.CHAT} ${exports.SUBCOMMANDS.CHAT.LIST}`]: 'List available chat models',
164
+ };
@@ -12,6 +12,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ApiKeyService = void 0;
13
13
  const client_1 = require("../client");
14
14
  const error_handler_1 = require("../utils/error-handler");
15
+ const command_structure_1 = require("../constants/command-structure");
16
+ /**
17
+ * Service for managing API keys
18
+ * Command group: api-keys
19
+ */
15
20
  class ApiKeyService {
16
21
  constructor() {
17
22
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -22,7 +27,11 @@ class ApiKeyService {
22
27
  }
23
28
  return ApiKeyService.instance;
24
29
  }
25
- listApiKeys() {
30
+ /**
31
+ * List all API keys
32
+ * Command: berget api-keys list
33
+ */
34
+ list() {
26
35
  return __awaiter(this, void 0, void 0, function* () {
27
36
  try {
28
37
  const { data, error } = yield this.client.GET('/v1/api-keys');
@@ -46,7 +55,11 @@ class ApiKeyService {
46
55
  }
47
56
  });
48
57
  }
49
- createApiKey(options) {
58
+ /**
59
+ * Create a new API key
60
+ * Command: berget api-keys create
61
+ */
62
+ create(options) {
50
63
  return __awaiter(this, void 0, void 0, function* () {
51
64
  try {
52
65
  const { data, error } = yield this.client.POST('/v1/api-keys', {
@@ -62,7 +75,11 @@ class ApiKeyService {
62
75
  }
63
76
  });
64
77
  }
65
- deleteApiKey(id) {
78
+ /**
79
+ * Delete an API key
80
+ * Command: berget api-keys delete
81
+ */
82
+ delete(id) {
66
83
  return __awaiter(this, void 0, void 0, function* () {
67
84
  try {
68
85
  const { error } = yield this.client.DELETE('/v1/api-keys/{id}', {
@@ -78,7 +95,11 @@ class ApiKeyService {
78
95
  }
79
96
  });
80
97
  }
81
- rotateApiKey(id) {
98
+ /**
99
+ * Rotate an API key
100
+ * Command: berget api-keys rotate
101
+ */
102
+ rotate(id) {
82
103
  return __awaiter(this, void 0, void 0, function* () {
83
104
  try {
84
105
  const { data, error } = yield this.client.PUT('/v1/api-keys/{id}/rotate', {
@@ -94,7 +115,11 @@ class ApiKeyService {
94
115
  }
95
116
  });
96
117
  }
97
- getApiKeyUsage(id) {
118
+ /**
119
+ * Get usage statistics for an API key
120
+ * Command: berget api-keys describe
121
+ */
122
+ describe(id) {
98
123
  return __awaiter(this, void 0, void 0, function* () {
99
124
  try {
100
125
  const { data, error } = yield this.client.GET('/v1/api-keys/{id}/usage', {
@@ -112,3 +137,7 @@ class ApiKeyService {
112
137
  }
113
138
  }
114
139
  exports.ApiKeyService = ApiKeyService;
140
+ // Command group name for this service
141
+ ApiKeyService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.API_KEYS;
142
+ // Subcommands for this service
143
+ ApiKeyService.COMMANDS = command_structure_1.SUBCOMMANDS.API_KEYS;
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -14,9 +37,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
37
  Object.defineProperty(exports, "__esModule", { value: true });
15
38
  exports.AuthService = void 0;
16
39
  const client_1 = require("../client");
17
- const open_1 = __importDefault(require("open"));
40
+ // We'll use dynamic import for 'open' to support ESM modules in CommonJS
18
41
  const chalk_1 = __importDefault(require("chalk"));
19
42
  const error_handler_1 = require("../utils/error-handler");
43
+ const command_structure_1 = require("../constants/command-structure");
44
+ /**
45
+ * Service for authentication operations
46
+ * Command group: auth
47
+ */
20
48
  class AuthService {
21
49
  constructor() {
22
50
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -27,6 +55,21 @@ class AuthService {
27
55
  }
28
56
  return AuthService.instance;
29
57
  }
58
+ whoami() {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ try {
61
+ const { data: profile, error } = yield this.client.GET('/v1/users/me');
62
+ if (error) {
63
+ throw new Error(error ? JSON.stringify(error) : 'Failed to get user profile');
64
+ }
65
+ return profile;
66
+ }
67
+ catch (error) {
68
+ (0, error_handler_1.handleError)('Failed to get user profile', error);
69
+ return null;
70
+ }
71
+ });
72
+ }
30
73
  login() {
31
74
  return __awaiter(this, void 0, void 0, function* () {
32
75
  try {
@@ -40,14 +83,20 @@ class AuthService {
40
83
  ? JSON.stringify(deviceError)
41
84
  : 'Failed to get device authorization data');
42
85
  }
86
+ // Type assertion for deviceData
87
+ const typedDeviceData = deviceData;
43
88
  // Display information to user
44
89
  console.log(chalk_1.default.cyan('\nTo complete login:'));
45
- console.log(chalk_1.default.cyan(`1. Open this URL: ${chalk_1.default.bold(deviceData.verification_url || 'https://auth.berget.ai/device')}`));
46
- console.log(chalk_1.default.cyan(`2. Enter this code: ${chalk_1.default.bold(deviceData.user_code || '')}\n`));
90
+ console.log(chalk_1.default.cyan(`1. Open this URL: ${chalk_1.default.bold(typedDeviceData.verification_url ||
91
+ 'https://keycloak.berget.ai/device')}`));
92
+ if (!typedDeviceData.verification_url)
93
+ console.log(chalk_1.default.cyan(`2. Enter this code: ${chalk_1.default.bold(typedDeviceData.user_code || '')}\n`));
47
94
  // Try to open browser automatically
48
95
  try {
49
- if (deviceData.verification_url) {
50
- yield (0, open_1.default)(deviceData.verification_url);
96
+ if (typedDeviceData.verification_url) {
97
+ // Use dynamic import for the 'open' package
98
+ const open = yield Promise.resolve().then(() => __importStar(require('open'))).then((m) => m.default);
99
+ yield open(typedDeviceData.verification_url);
51
100
  console.log(chalk_1.default.dim("Browser opened automatically. If it didn't open, please use the URL above."));
52
101
  }
53
102
  }
@@ -57,9 +106,11 @@ class AuthService {
57
106
  console.log(chalk_1.default.dim('\nWaiting for authentication to complete...'));
58
107
  // Step 2: Poll for completion
59
108
  const startTime = Date.now();
60
- const expiresIn = deviceData.expires_in !== undefined ? deviceData.expires_in : 900;
109
+ const expiresIn = typedDeviceData.expires_in !== undefined
110
+ ? typedDeviceData.expires_in
111
+ : 900;
61
112
  const expiresAt = startTime + expiresIn * 1000;
62
- let pollInterval = (deviceData.interval || 5) * 1000;
113
+ let pollInterval = (typedDeviceData.interval || 5) * 1000;
63
114
  const spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
64
115
  let spinnerIdx = 0;
65
116
  while (Date.now() < expiresAt) {
@@ -69,7 +120,7 @@ class AuthService {
69
120
  process.stdout.write(`\r${chalk_1.default.blue(spinner[spinnerIdx])} Waiting for authentication...`);
70
121
  spinnerIdx = (spinnerIdx + 1) % spinner.length;
71
122
  // Check if authentication is complete
72
- const deviceCode = deviceData.device_code || '';
123
+ const deviceCode = typedDeviceData.device_code || '';
73
124
  const { data: tokenData, error: tokenError } = yield client_1.apiClient.POST('/v1/auth/device/token', {
74
125
  body: {
75
126
  device_code: deviceCode,
@@ -117,16 +168,27 @@ class AuthService {
117
168
  continue;
118
169
  }
119
170
  }
120
- else if (tokenData && tokenData.token) {
121
- // Success!
122
- (0, client_1.saveAuthToken)(tokenData.token);
123
- process.stdout.write('\r' + ' '.repeat(50) + '\r'); // Clear the spinner line
124
- console.log(chalk_1.default.green('✓ Successfully logged in to Berget'));
125
- if (tokenData.user) {
126
- const user = tokenData.user;
127
- console.log(chalk_1.default.green(`Logged in as ${user.name || user.email || 'User'}`));
171
+ else if (tokenData) {
172
+ // Type assertion for tokenData
173
+ const typedTokenData = tokenData;
174
+ if (typedTokenData.token) {
175
+ // Success!
176
+ (0, client_1.saveAuthToken)(typedTokenData.token, typedTokenData.refresh_token || '', typedTokenData.expires_in || 3600);
177
+ if (process.argv.includes('--debug')) {
178
+ console.log(chalk_1.default.yellow('DEBUG: Token data received:'));
179
+ console.log(chalk_1.default.yellow(JSON.stringify({
180
+ expires_in: typedTokenData.expires_in,
181
+ refresh_expires_in: typedTokenData.refresh_expires_in,
182
+ }, null, 2)));
183
+ }
184
+ process.stdout.write('\r' + ' '.repeat(50) + '\r'); // Clear the spinner line
185
+ console.log(chalk_1.default.green('✓ Successfully logged in to Berget'));
186
+ if (typedTokenData.user) {
187
+ const user = typedTokenData.user;
188
+ console.log(chalk_1.default.green(`Logged in as ${user.name || user.email || 'User'}`));
189
+ }
190
+ return true;
128
191
  }
129
- return true;
130
192
  }
131
193
  }
132
194
  console.log(chalk_1.default.red('\n\nAuthentication timed out. Please try again.'));
@@ -138,31 +200,9 @@ class AuthService {
138
200
  }
139
201
  });
140
202
  }
141
- isAuthenticated() {
142
- return __awaiter(this, void 0, void 0, function* () {
143
- try {
144
- // Call an API endpoint that requires authentication
145
- const { data, error } = yield this.client.GET('/v1/users/me');
146
- return !!data && !error;
147
- }
148
- catch (_a) {
149
- return false;
150
- }
151
- });
152
- }
153
- getUserProfile() {
154
- return __awaiter(this, void 0, void 0, function* () {
155
- try {
156
- const { data, error } = yield this.client.GET('/v1/users/me');
157
- if (error)
158
- throw new Error(JSON.stringify(error));
159
- return data;
160
- }
161
- catch (error) {
162
- (0, error_handler_1.handleError)('Failed to get user profile', error);
163
- throw error;
164
- }
165
- });
166
- }
167
203
  }
168
204
  exports.AuthService = AuthService;
205
+ // Command group name for this service
206
+ AuthService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.AUTH;
207
+ // Subcommands for this service
208
+ AuthService.COMMANDS = command_structure_1.SUBCOMMANDS.AUTH;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
22
+ var __importDefault = (this && this.__importDefault) || function (mod) {
23
+ return (mod && mod.__esModule) ? mod : { "default": mod };
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ChatService = void 0;
27
+ const client_1 = require("../client");
28
+ const chalk_1 = __importDefault(require("chalk"));
29
+ /**
30
+ * Service for interacting with the chat API
31
+ * Command group: chat
32
+ */
33
+ class ChatService {
34
+ constructor() {
35
+ this.client = (0, client_1.createAuthenticatedClient)();
36
+ }
37
+ static getInstance() {
38
+ if (!ChatService.instance) {
39
+ ChatService.instance = new ChatService();
40
+ }
41
+ return ChatService.instance;
42
+ }
43
+ /**
44
+ * Create a chat completion
45
+ * Command: berget chat completion
46
+ */
47
+ createCompletion(options) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ try {
50
+ const headers = {};
51
+ // Check if debug is enabled
52
+ const isDebug = process.argv.includes('--debug');
53
+ if (isDebug) {
54
+ console.log(chalk_1.default.yellow('DEBUG: Chat completion options:'));
55
+ console.log(chalk_1.default.yellow(JSON.stringify(options, null, 2)));
56
+ }
57
+ // If an API key is provided, use it for this request
58
+ if (options.apiKey) {
59
+ headers['Authorization'] = `Bearer ${options.apiKey}`;
60
+ // Remove apiKey from options before sending to API
61
+ const { apiKey } = options, requestOptions = __rest(options, ["apiKey"]);
62
+ if (isDebug) {
63
+ console.log(chalk_1.default.yellow('DEBUG: Using provided API key'));
64
+ console.log(chalk_1.default.yellow('DEBUG: Request options:'));
65
+ console.log(chalk_1.default.yellow(JSON.stringify(requestOptions, null, 2)));
66
+ }
67
+ const { data, error } = yield this.client.POST('/v1/chat/completions', {
68
+ body: requestOptions,
69
+ headers
70
+ });
71
+ if (isDebug) {
72
+ console.log(chalk_1.default.yellow('DEBUG: API response:'));
73
+ console.log(chalk_1.default.yellow(JSON.stringify({ data, error }, null, 2)));
74
+ // Output the complete response data for debugging
75
+ console.log(chalk_1.default.yellow('DEBUG: Complete response data:'));
76
+ console.log(chalk_1.default.yellow(JSON.stringify(data, null, 2)));
77
+ }
78
+ if (error)
79
+ throw new Error(JSON.stringify(error));
80
+ return data;
81
+ }
82
+ else {
83
+ // Use the default authenticated client
84
+ if (isDebug) {
85
+ console.log(chalk_1.default.yellow('DEBUG: Using default authentication'));
86
+ }
87
+ const { data, error } = yield this.client.POST('/v1/chat/completions', {
88
+ body: options
89
+ });
90
+ if (isDebug) {
91
+ console.log(chalk_1.default.yellow('DEBUG: API response:'));
92
+ console.log(chalk_1.default.yellow(JSON.stringify({ data, error }, null, 2)));
93
+ // Output the complete response data for debugging
94
+ console.log(chalk_1.default.yellow('DEBUG: Complete response data:'));
95
+ console.log(chalk_1.default.yellow(JSON.stringify(data, null, 2)));
96
+ }
97
+ if (error)
98
+ throw new Error(JSON.stringify(error));
99
+ return data;
100
+ }
101
+ }
102
+ catch (error) {
103
+ // Improved error handling
104
+ let errorMessage = 'Failed to create chat completion';
105
+ if (error instanceof Error) {
106
+ try {
107
+ // Try to parse the error message as JSON
108
+ const parsedError = JSON.parse(error.message);
109
+ if (parsedError.error && parsedError.error.message) {
110
+ errorMessage = `Chat error: ${parsedError.error.message}`;
111
+ }
112
+ }
113
+ catch (e) {
114
+ // If parsing fails, use the original error message
115
+ errorMessage = `Chat error: ${error.message}`;
116
+ }
117
+ }
118
+ console.error(chalk_1.default.red(errorMessage));
119
+ throw new Error(errorMessage);
120
+ }
121
+ });
122
+ }
123
+ /**
124
+ * List available models
125
+ * Command: berget chat list
126
+ */
127
+ listModels(apiKey) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ try {
130
+ if (apiKey) {
131
+ const headers = {
132
+ 'Authorization': `Bearer ${apiKey}`
133
+ };
134
+ const { data, error } = yield this.client.GET('/v1/models', { headers });
135
+ if (error)
136
+ throw new Error(JSON.stringify(error));
137
+ return data;
138
+ }
139
+ else {
140
+ const { data, error } = yield this.client.GET('/v1/models');
141
+ if (error)
142
+ throw new Error(JSON.stringify(error));
143
+ return data;
144
+ }
145
+ }
146
+ catch (error) {
147
+ // Improved error handling
148
+ let errorMessage = 'Failed to list models';
149
+ if (error instanceof Error) {
150
+ try {
151
+ // Try to parse the error message as JSON
152
+ const parsedError = JSON.parse(error.message);
153
+ if (parsedError.error) {
154
+ errorMessage = `Models error: ${typeof parsedError.error === 'string' ?
155
+ parsedError.error :
156
+ (parsedError.error.message || JSON.stringify(parsedError.error))}`;
157
+ }
158
+ }
159
+ catch (e) {
160
+ // If parsing fails, use the original error message
161
+ errorMessage = `Models error: ${error.message}`;
162
+ }
163
+ }
164
+ console.error(chalk_1.default.red(errorMessage));
165
+ throw new Error(errorMessage);
166
+ }
167
+ });
168
+ }
169
+ }
170
+ exports.ChatService = ChatService;
171
+ // Command group name for this service
172
+ ChatService.COMMAND_GROUP = 'chat';
173
+ // Subcommands for this service
174
+ ChatService.COMMANDS = {
175
+ RUN: 'run',
176
+ LIST: 'list'
177
+ };
@@ -11,6 +11,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ClusterService = void 0;
13
13
  const client_1 = require("../client");
14
+ const command_structure_1 = require("../constants/command-structure");
15
+ /**
16
+ * Service for managing Kubernetes clusters
17
+ * Command group: clusters
18
+ */
14
19
  class ClusterService {
15
20
  constructor() {
16
21
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -21,7 +26,11 @@ class ClusterService {
21
26
  }
22
27
  return ClusterService.instance;
23
28
  }
24
- getClusterUsage(clusterId) {
29
+ /**
30
+ * Get resource usage for a cluster
31
+ * Command: berget clusters get-usage
32
+ */
33
+ getUsage(clusterId) {
25
34
  return __awaiter(this, void 0, void 0, function* () {
26
35
  try {
27
36
  const { data, error } = yield this.client.GET('/v1/clusters/{clusterId}/usage', {
@@ -37,7 +46,11 @@ class ClusterService {
37
46
  }
38
47
  });
39
48
  }
40
- listClusters() {
49
+ /**
50
+ * List all clusters
51
+ * Command: berget clusters list
52
+ */
53
+ list() {
41
54
  return __awaiter(this, void 0, void 0, function* () {
42
55
  try {
43
56
  const { data, error } = yield this.client.GET('/v1/clusters');
@@ -51,5 +64,27 @@ class ClusterService {
51
64
  }
52
65
  });
53
66
  }
67
+ /**
68
+ * Get detailed information about a cluster
69
+ * Command: berget clusters describe
70
+ */
71
+ describe(clusterId) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ try {
74
+ // This is a placeholder since the API doesn't have a specific endpoint
75
+ // In a real implementation, this would call a specific endpoint
76
+ const clusters = yield this.list();
77
+ return clusters.find(cluster => cluster.id === clusterId) || null;
78
+ }
79
+ catch (error) {
80
+ console.error('Failed to describe cluster:', error);
81
+ throw error;
82
+ }
83
+ });
84
+ }
54
85
  }
55
86
  exports.ClusterService = ClusterService;
87
+ // Command group name for this service
88
+ ClusterService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.CLUSTERS;
89
+ // Subcommands for this service
90
+ ClusterService.COMMANDS = command_structure_1.SUBCOMMANDS.CLUSTERS;