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
@@ -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.CollaboratorService = void 0;
13
13
  const client_1 = require("../client");
14
+ const command_structure_1 = require("../constants/command-structure");
15
+ /**
16
+ * Service for managing collaborators
17
+ * Command group: users
18
+ */
14
19
  class CollaboratorService {
15
20
  constructor() {
16
21
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -21,17 +26,29 @@ class CollaboratorService {
21
26
  }
22
27
  return CollaboratorService.instance;
23
28
  }
24
- // This endpoint is not available in the API
25
- addCollaborator(clusterId, githubUsername) {
29
+ /**
30
+ * Invite a new collaborator
31
+ * Command: berget users invite
32
+ * This endpoint is not available in the API
33
+ */
34
+ invite(clusterId, githubUsername) {
26
35
  return __awaiter(this, void 0, void 0, function* () {
27
36
  throw new Error('This functionality is not available in the API');
28
37
  });
29
38
  }
30
- // This endpoint is not available in the API
31
- listCollaborators(clusterId) {
39
+ /**
40
+ * List all collaborators
41
+ * Command: berget users list
42
+ * This endpoint is not available in the API
43
+ */
44
+ list(clusterId) {
32
45
  return __awaiter(this, void 0, void 0, function* () {
33
46
  throw new Error('This functionality is not available in the API');
34
47
  });
35
48
  }
36
49
  }
37
50
  exports.CollaboratorService = CollaboratorService;
51
+ // Command group name for this service
52
+ CollaboratorService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.USERS;
53
+ // Subcommands for this service
54
+ CollaboratorService.COMMANDS = command_structure_1.SUBCOMMANDS.USERS;
@@ -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.FluxService = void 0;
13
13
  const client_1 = require("../client");
14
+ const command_structure_1 = require("../constants/command-structure");
15
+ /**
16
+ * Service for managing Flux CD
17
+ * Command group: flux
18
+ */
14
19
  class FluxService {
15
20
  constructor() {
16
21
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -21,17 +26,29 @@ class FluxService {
21
26
  }
22
27
  return FluxService.instance;
23
28
  }
24
- // This endpoint is not available in the API
25
- installFlux(options) {
29
+ /**
30
+ * Install Flux CD
31
+ * Command: berget flux install
32
+ * This endpoint is not available in the API
33
+ */
34
+ install(options) {
26
35
  return __awaiter(this, void 0, void 0, function* () {
27
36
  throw new Error('This functionality is not available in the API');
28
37
  });
29
38
  }
30
- // This endpoint is not available in the API
31
- bootstrapFlux(options) {
39
+ /**
40
+ * Bootstrap Flux CD
41
+ * Command: berget flux bootstrap
42
+ * This endpoint is not available in the API
43
+ */
44
+ bootstrap(options) {
32
45
  return __awaiter(this, void 0, void 0, function* () {
33
46
  throw new Error('This functionality is not available in the API');
34
47
  });
35
48
  }
36
49
  }
37
50
  exports.FluxService = FluxService;
51
+ // Command group name for this service
52
+ FluxService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.FLUX;
53
+ // Subcommands for this service
54
+ FluxService.COMMANDS = command_structure_1.SUBCOMMANDS.FLUX;
@@ -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.HelmService = void 0;
13
13
  const client_1 = require("../client");
14
+ const command_structure_1 = require("../constants/command-structure");
15
+ /**
16
+ * Service for managing Helm charts
17
+ * Command group: helm
18
+ */
14
19
  class HelmService {
15
20
  constructor() {
16
21
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -21,17 +26,29 @@ class HelmService {
21
26
  }
22
27
  return HelmService.instance;
23
28
  }
24
- // This endpoint is not available in the API
29
+ /**
30
+ * Add a Helm repository
31
+ * Command: berget helm add-repo
32
+ * This endpoint is not available in the API
33
+ */
25
34
  addRepo(options) {
26
35
  return __awaiter(this, void 0, void 0, function* () {
27
36
  throw new Error('This functionality is not available in the API');
28
37
  });
29
38
  }
30
- // This endpoint is not available in the API
31
- installChart(options) {
39
+ /**
40
+ * Install a Helm chart
41
+ * Command: berget helm install
42
+ * This endpoint is not available in the API
43
+ */
44
+ install(options) {
32
45
  return __awaiter(this, void 0, void 0, function* () {
33
46
  throw new Error('This functionality is not available in the API');
34
47
  });
35
48
  }
36
49
  }
37
50
  exports.HelmService = HelmService;
51
+ // Command group name for this service
52
+ HelmService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.HELM;
53
+ // Subcommands for this service
54
+ HelmService.COMMANDS = command_structure_1.SUBCOMMANDS.HELM;
@@ -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.KubectlService = void 0;
13
13
  const client_1 = require("../client");
14
+ const command_structure_1 = require("../constants/command-structure");
15
+ /**
16
+ * Service for managing Kubernetes resources
17
+ * Command group: kubectl
18
+ */
14
19
  class KubectlService {
15
20
  constructor() {
16
21
  this.client = (0, client_1.createAuthenticatedClient)();
@@ -21,23 +26,39 @@ class KubectlService {
21
26
  }
22
27
  return KubectlService.instance;
23
28
  }
24
- // This endpoint is not available in the API
29
+ /**
30
+ * Create a Kubernetes namespace
31
+ * Command: berget kubectl create-namespace
32
+ * This endpoint is not available in the API
33
+ */
25
34
  createNamespace(name) {
26
35
  return __awaiter(this, void 0, void 0, function* () {
27
36
  throw new Error('This functionality is not available in the API');
28
37
  });
29
38
  }
30
- // This endpoint is not available in the API
31
- applyConfiguration(filename) {
39
+ /**
40
+ * Apply a Kubernetes configuration
41
+ * Command: berget kubectl apply
42
+ * This endpoint is not available in the API
43
+ */
44
+ apply(filename) {
32
45
  return __awaiter(this, void 0, void 0, function* () {
33
46
  throw new Error('This functionality is not available in the API');
34
47
  });
35
48
  }
36
- // This endpoint is not available in the API
37
- getResources(resource, namespace) {
49
+ /**
50
+ * Get Kubernetes resources
51
+ * Command: berget kubectl get
52
+ * This endpoint is not available in the API
53
+ */
54
+ get(resource, namespace) {
38
55
  return __awaiter(this, void 0, void 0, function* () {
39
56
  throw new Error('This functionality is not available in the API');
40
57
  });
41
58
  }
42
59
  }
43
60
  exports.KubectlService = KubectlService;
61
+ // Command group name for this service
62
+ KubectlService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.KUBECTL;
63
+ // Subcommands for this service
64
+ KubectlService.COMMANDS = command_structure_1.SUBCOMMANDS.KUBECTL;
@@ -0,0 +1,50 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.checkBergetConfig = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ /**
30
+ * Check for .bergetconfig file and handle cluster switching
31
+ */
32
+ function checkBergetConfig() {
33
+ const configPath = path.join(process.cwd(), '.bergetconfig');
34
+ if (fs.existsSync(configPath)) {
35
+ try {
36
+ const config = fs.readFileSync(configPath, 'utf8');
37
+ const match = config.match(/cluster:\s*(.+)/);
38
+ if (match && match[1]) {
39
+ const clusterName = match[1].trim();
40
+ console.log(`🔄 Berget: Switched to cluster "${clusterName}"`);
41
+ console.log('✓ kubectl config updated');
42
+ console.log('');
43
+ }
44
+ }
45
+ catch (error) {
46
+ // Silently ignore errors reading config
47
+ }
48
+ }
49
+ }
50
+ exports.checkBergetConfig = checkBergetConfig;
@@ -0,0 +1,111 @@
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 __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.DefaultApiKeyManager = void 0;
30
+ const fs = __importStar(require("fs"));
31
+ const path = __importStar(require("path"));
32
+ const os = __importStar(require("os"));
33
+ const chalk_1 = __importDefault(require("chalk"));
34
+ /**
35
+ * Manages the default API key for chat commands
36
+ */
37
+ class DefaultApiKeyManager {
38
+ constructor() {
39
+ this.defaultApiKey = null;
40
+ // Set up config file path in user's home directory
41
+ const bergetDir = path.join(os.homedir(), '.berget');
42
+ if (!fs.existsSync(bergetDir)) {
43
+ fs.mkdirSync(bergetDir, { recursive: true });
44
+ }
45
+ this.configFilePath = path.join(bergetDir, 'default-api-key.json');
46
+ this.loadConfig();
47
+ }
48
+ static getInstance() {
49
+ if (!DefaultApiKeyManager.instance) {
50
+ DefaultApiKeyManager.instance = new DefaultApiKeyManager();
51
+ }
52
+ return DefaultApiKeyManager.instance;
53
+ }
54
+ /**
55
+ * Load default API key from file
56
+ */
57
+ loadConfig() {
58
+ try {
59
+ if (fs.existsSync(this.configFilePath)) {
60
+ const data = fs.readFileSync(this.configFilePath, 'utf8');
61
+ this.defaultApiKey = JSON.parse(data);
62
+ }
63
+ }
64
+ catch (error) {
65
+ console.error(chalk_1.default.dim('Failed to load default API key configuration'));
66
+ this.defaultApiKey = null;
67
+ }
68
+ }
69
+ /**
70
+ * Save default API key to file
71
+ */
72
+ saveConfig() {
73
+ try {
74
+ if (this.defaultApiKey) {
75
+ fs.writeFileSync(this.configFilePath, JSON.stringify(this.defaultApiKey, null, 2));
76
+ // Set file permissions to be readable only by the owner
77
+ fs.chmodSync(this.configFilePath, 0o600);
78
+ }
79
+ else {
80
+ // If default API key is null, remove the file
81
+ if (fs.existsSync(this.configFilePath)) {
82
+ fs.unlinkSync(this.configFilePath);
83
+ }
84
+ }
85
+ }
86
+ catch (error) {
87
+ console.error(chalk_1.default.dim('Failed to save default API key configuration'));
88
+ }
89
+ }
90
+ /**
91
+ * Set the default API key
92
+ */
93
+ setDefaultApiKey(id, name, prefix) {
94
+ this.defaultApiKey = { id, name, prefix };
95
+ this.saveConfig();
96
+ }
97
+ /**
98
+ * Get the default API key
99
+ */
100
+ getDefaultApiKey() {
101
+ return this.defaultApiKey;
102
+ }
103
+ /**
104
+ * Clear the default API key
105
+ */
106
+ clearDefaultApiKey() {
107
+ this.defaultApiKey = null;
108
+ this.saveConfig();
109
+ }
110
+ }
111
+ exports.DefaultApiKeyManager = DefaultApiKeyManager;
@@ -0,0 +1,165 @@
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 __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.TokenManager = void 0;
30
+ const fs = __importStar(require("fs"));
31
+ const path = __importStar(require("path"));
32
+ const os = __importStar(require("os"));
33
+ const chalk_1 = __importDefault(require("chalk"));
34
+ /**
35
+ * Manages authentication tokens including refresh functionality
36
+ */
37
+ class TokenManager {
38
+ constructor() {
39
+ this.tokenData = null;
40
+ // Set up token file path in user's home directory
41
+ const bergetDir = path.join(os.homedir(), '.berget');
42
+ if (!fs.existsSync(bergetDir)) {
43
+ fs.mkdirSync(bergetDir, { recursive: true });
44
+ }
45
+ this.tokenFilePath = path.join(bergetDir, 'auth.json');
46
+ this.loadToken();
47
+ }
48
+ static getInstance() {
49
+ if (!TokenManager.instance) {
50
+ TokenManager.instance = new TokenManager();
51
+ }
52
+ return TokenManager.instance;
53
+ }
54
+ /**
55
+ * Load token data from file
56
+ */
57
+ loadToken() {
58
+ try {
59
+ if (fs.existsSync(this.tokenFilePath)) {
60
+ const data = fs.readFileSync(this.tokenFilePath, 'utf8');
61
+ this.tokenData = JSON.parse(data);
62
+ }
63
+ }
64
+ catch (error) {
65
+ console.error(chalk_1.default.dim('Failed to load authentication token'));
66
+ this.tokenData = null;
67
+ }
68
+ }
69
+ /**
70
+ * Save token data to file
71
+ */
72
+ saveToken() {
73
+ try {
74
+ if (this.tokenData) {
75
+ fs.writeFileSync(this.tokenFilePath, JSON.stringify(this.tokenData, null, 2));
76
+ // Set file permissions to be readable only by the owner
77
+ fs.chmodSync(this.tokenFilePath, 0o600);
78
+ }
79
+ else {
80
+ // If token data is null, remove the file
81
+ if (fs.existsSync(this.tokenFilePath)) {
82
+ fs.unlinkSync(this.tokenFilePath);
83
+ }
84
+ }
85
+ }
86
+ catch (error) {
87
+ console.error(chalk_1.default.dim('Failed to save authentication token'));
88
+ }
89
+ }
90
+ /**
91
+ * Get the current access token
92
+ * @returns The access token or null if not available
93
+ */
94
+ getAccessToken() {
95
+ if (!this.tokenData)
96
+ return null;
97
+ return this.tokenData.access_token;
98
+ }
99
+ /**
100
+ * Get the refresh token
101
+ * @returns The refresh token or null if not available
102
+ */
103
+ getRefreshToken() {
104
+ if (!this.tokenData)
105
+ return null;
106
+ return this.tokenData.refresh_token;
107
+ }
108
+ /**
109
+ * Check if the access token is expired
110
+ * @returns true if expired or about to expire (within 5 minutes), false otherwise
111
+ */
112
+ isTokenExpired() {
113
+ if (!this.tokenData || !this.tokenData.expires_at)
114
+ return true;
115
+ try {
116
+ // Consider token expired if it's within 10 minutes of expiration
117
+ // Using a larger buffer to be more proactive about refreshing
118
+ const expirationBuffer = 10 * 60 * 1000; // 10 minutes in milliseconds
119
+ const isExpired = Date.now() + expirationBuffer >= this.tokenData.expires_at;
120
+ if (isExpired && process.argv.includes('--debug')) {
121
+ console.log(chalk_1.default.yellow(`DEBUG: Token expired or expiring soon. Current time: ${new Date().toISOString()}, Expiry: ${new Date(this.tokenData.expires_at).toISOString()}`));
122
+ }
123
+ return isExpired;
124
+ }
125
+ catch (error) {
126
+ // If there's any error checking expiration, assume token is expired
127
+ console.error(chalk_1.default.dim(`Error checking token expiration: ${error instanceof Error ? error.message : String(error)}`));
128
+ return true;
129
+ }
130
+ }
131
+ /**
132
+ * Set new token data
133
+ * @param accessToken The new access token
134
+ * @param refreshToken The new refresh token
135
+ * @param expiresIn Expiration time in seconds
136
+ */
137
+ setTokens(accessToken, refreshToken, expiresIn) {
138
+ this.tokenData = {
139
+ access_token: accessToken,
140
+ refresh_token: refreshToken,
141
+ expires_at: Date.now() + (expiresIn * 1000)
142
+ };
143
+ this.saveToken();
144
+ }
145
+ /**
146
+ * Update just the access token and its expiration
147
+ * @param accessToken The new access token
148
+ * @param expiresIn Expiration time in seconds
149
+ */
150
+ updateAccessToken(accessToken, expiresIn) {
151
+ if (!this.tokenData)
152
+ return;
153
+ this.tokenData.access_token = accessToken;
154
+ this.tokenData.expires_at = Date.now() + (expiresIn * 1000);
155
+ this.saveToken();
156
+ }
157
+ /**
158
+ * Clear all token data
159
+ */
160
+ clearTokens() {
161
+ this.tokenData = null;
162
+ this.saveToken();
163
+ }
164
+ }
165
+ exports.TokenManager = TokenManager;