berget 2.2.7 → 2.2.9

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 (130) hide show
  1. package/.github/workflows/publish.yml +6 -6
  2. package/.github/workflows/test.yml +1 -1
  3. package/.prettierrc +5 -3
  4. package/dist/index.js +24 -25
  5. package/dist/package.json +7 -3
  6. package/dist/src/agents/app.js +8 -8
  7. package/dist/src/agents/backend.js +3 -3
  8. package/dist/src/agents/devops.js +8 -8
  9. package/dist/src/agents/frontend.js +3 -3
  10. package/dist/src/agents/fullstack.js +3 -3
  11. package/dist/src/agents/index.js +18 -18
  12. package/dist/src/agents/quality.js +8 -8
  13. package/dist/src/agents/security.js +8 -8
  14. package/dist/src/client.js +115 -127
  15. package/dist/src/commands/api-keys.js +181 -202
  16. package/dist/src/commands/auth.js +16 -25
  17. package/dist/src/commands/autocomplete.js +8 -8
  18. package/dist/src/commands/billing.js +10 -19
  19. package/dist/src/commands/chat.js +139 -170
  20. package/dist/src/commands/clusters.js +21 -30
  21. package/dist/src/commands/code/__tests__/auth-sync.test.js +189 -186
  22. package/dist/src/commands/code/__tests__/fake-api-key-service.js +3 -13
  23. package/dist/src/commands/code/__tests__/fake-auth-service.js +21 -29
  24. package/dist/src/commands/code/__tests__/fake-command-runner.js +22 -33
  25. package/dist/src/commands/code/__tests__/fake-file-store.js +19 -41
  26. package/dist/src/commands/code/__tests__/fake-prompter.js +81 -97
  27. package/dist/src/commands/code/__tests__/setup-flow.test.js +295 -295
  28. package/dist/src/commands/code/adapters/clack-prompter.js +15 -32
  29. package/dist/src/commands/code/adapters/fs-file-store.js +25 -44
  30. package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -41
  31. package/dist/src/commands/code/auth-sync.js +215 -228
  32. package/dist/src/commands/code/errors.js +15 -12
  33. package/dist/src/commands/code/setup.js +390 -425
  34. package/dist/src/commands/code.js +279 -294
  35. package/dist/src/commands/index.js +5 -5
  36. package/dist/src/commands/models.js +16 -25
  37. package/dist/src/commands/users.js +9 -18
  38. package/dist/src/constants/command-structure.js +138 -138
  39. package/dist/src/services/api-key-service.js +132 -152
  40. package/dist/src/services/auth-service.js +81 -95
  41. package/dist/src/services/browser-auth.js +121 -131
  42. package/dist/src/services/chat-service.js +369 -386
  43. package/dist/src/services/cluster-service.js +47 -62
  44. package/dist/src/services/collaborator-service.js +9 -21
  45. package/dist/src/services/flux-service.js +13 -25
  46. package/dist/src/services/helm-service.js +9 -21
  47. package/dist/src/services/kubectl-service.js +15 -29
  48. package/dist/src/utils/config-checker.js +8 -8
  49. package/dist/src/utils/config-loader.js +109 -109
  50. package/dist/src/utils/default-api-key.js +129 -139
  51. package/dist/src/utils/env-manager.js +55 -66
  52. package/dist/src/utils/error-handler.js +62 -62
  53. package/dist/src/utils/logger.js +74 -67
  54. package/dist/src/utils/markdown-renderer.js +28 -28
  55. package/dist/src/utils/opencode-validator.js +67 -69
  56. package/dist/src/utils/token-manager.js +67 -65
  57. package/dist/tests/commands/chat.test.js +30 -39
  58. package/dist/tests/commands/code.test.js +186 -195
  59. package/dist/tests/utils/config-loader.test.js +107 -107
  60. package/dist/tests/utils/env-manager.test.js +81 -90
  61. package/dist/tests/utils/opencode-validator.test.js +42 -41
  62. package/dist/vitest.config.js +1 -1
  63. package/eslint.config.mjs +65 -30
  64. package/index.ts +30 -31
  65. package/package.json +7 -3
  66. package/src/agents/app.ts +9 -9
  67. package/src/agents/backend.ts +4 -4
  68. package/src/agents/devops.ts +9 -9
  69. package/src/agents/frontend.ts +4 -4
  70. package/src/agents/fullstack.ts +4 -4
  71. package/src/agents/index.ts +27 -25
  72. package/src/agents/quality.ts +9 -9
  73. package/src/agents/security.ts +9 -9
  74. package/src/agents/types.ts +10 -10
  75. package/src/client.ts +85 -77
  76. package/src/commands/api-keys.ts +180 -185
  77. package/src/commands/auth.ts +15 -14
  78. package/src/commands/autocomplete.ts +10 -10
  79. package/src/commands/billing.ts +13 -12
  80. package/src/commands/chat.ts +145 -142
  81. package/src/commands/clusters.ts +20 -19
  82. package/src/commands/code/__tests__/auth-sync.test.ts +176 -175
  83. package/src/commands/code/__tests__/fake-api-key-service.ts +2 -2
  84. package/src/commands/code/__tests__/fake-auth-service.ts +18 -18
  85. package/src/commands/code/__tests__/fake-command-runner.ts +28 -22
  86. package/src/commands/code/__tests__/fake-file-store.ts +15 -15
  87. package/src/commands/code/__tests__/fake-prompter.ts +86 -85
  88. package/src/commands/code/__tests__/setup-flow.test.ts +253 -251
  89. package/src/commands/code/adapters/clack-prompter.ts +32 -30
  90. package/src/commands/code/adapters/fs-file-store.ts +18 -17
  91. package/src/commands/code/adapters/spawn-command-runner.ts +20 -15
  92. package/src/commands/code/auth-sync.ts +210 -210
  93. package/src/commands/code/errors.ts +11 -11
  94. package/src/commands/code/ports/auth-services.ts +7 -7
  95. package/src/commands/code/ports/command-runner.ts +2 -2
  96. package/src/commands/code/ports/file-store.ts +3 -3
  97. package/src/commands/code/ports/prompter.ts +13 -13
  98. package/src/commands/code/setup.ts +408 -406
  99. package/src/commands/code.ts +288 -287
  100. package/src/commands/index.ts +11 -10
  101. package/src/commands/models.ts +19 -18
  102. package/src/commands/users.ts +11 -10
  103. package/src/constants/command-structure.ts +159 -159
  104. package/src/services/api-key-service.ts +85 -85
  105. package/src/services/auth-service.ts +55 -54
  106. package/src/services/browser-auth.ts +62 -62
  107. package/src/services/chat-service.ts +170 -171
  108. package/src/services/cluster-service.ts +28 -28
  109. package/src/services/collaborator-service.ts +6 -6
  110. package/src/services/flux-service.ts +17 -17
  111. package/src/services/helm-service.ts +11 -11
  112. package/src/services/kubectl-service.ts +12 -12
  113. package/src/types/api.d.ts +1933 -1933
  114. package/src/types/json.d.ts +1 -1
  115. package/src/utils/config-checker.ts +7 -7
  116. package/src/utils/config-loader.ts +130 -129
  117. package/src/utils/default-api-key.ts +81 -80
  118. package/src/utils/env-manager.ts +37 -37
  119. package/src/utils/error-handler.ts +64 -64
  120. package/src/utils/logger.ts +72 -66
  121. package/src/utils/markdown-renderer.ts +28 -28
  122. package/src/utils/opencode-validator.ts +72 -71
  123. package/src/utils/token-manager.ts +69 -68
  124. package/tests/commands/chat.test.ts +32 -31
  125. package/tests/commands/code.test.ts +182 -181
  126. package/tests/utils/config-loader.test.ts +111 -110
  127. package/tests/utils/env-manager.test.ts +83 -79
  128. package/tests/utils/opencode-validator.test.ts +43 -42
  129. package/tsconfig.json +2 -1
  130. package/vitest.config.ts +2 -2
@@ -1,194 +1,174 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.ApiKeyService = void 0;
13
4
  const client_1 = require("../client");
14
- const error_handler_1 = require("../utils/error-handler");
15
5
  const command_structure_1 = require("../constants/command-structure");
6
+ const error_handler_1 = require("../utils/error-handler");
16
7
  /**
17
8
  * Service for managing API keys
18
9
  * Command group: api-keys
19
10
  */
20
11
  class ApiKeyService {
21
- constructor() {
22
- this.client = (0, client_1.createAuthenticatedClient)();
23
- }
12
+ // Command group name for this service
13
+ static COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.API_KEYS;
14
+ // Subcommands for this service
15
+ static COMMANDS = command_structure_1.SUBCOMMANDS.API_KEYS;
16
+ static instance;
17
+ client = (0, client_1.createAuthenticatedClient)();
18
+ constructor() { }
24
19
  static getInstance() {
25
20
  if (!ApiKeyService.instance) {
26
21
  ApiKeyService.instance = new ApiKeyService();
27
22
  }
28
23
  return ApiKeyService.instance;
29
24
  }
30
- /**
31
- * List all API keys
32
- * Command: berget api-keys list
33
- */
34
- list() {
35
- return __awaiter(this, void 0, void 0, function* () {
36
- try {
37
- const { data, error } = yield this.client.GET("/v1/api-keys");
38
- if (error)
39
- throw error;
40
- return data || [];
41
- }
42
- catch (error) {
43
- (0, error_handler_1.handleError)("Failed to list API keys", error);
44
- throw error;
45
- }
46
- });
47
- }
48
25
  /**
49
26
  * Create a new API key
50
27
  * Command: berget api-keys create
51
28
  */
52
- create(options) {
53
- var _a, _b, _c, _d, _e;
54
- return __awaiter(this, void 0, void 0, function* () {
55
- try {
56
- // Validate input before sending request
57
- if (!options.name || options.name.trim().length === 0) {
58
- throw new Error("API key name is required and cannot be empty");
59
- }
60
- if (options.name.length > 100) {
61
- throw new Error("API key name must be 100 characters or less");
62
- }
63
- if (options.description && options.description.length > 500) {
64
- throw new Error("API key description must be 500 characters or less");
65
- }
66
- const { data, error } = yield this.client.POST("/v1/api-keys", {
67
- body: options,
68
- });
69
- if (error) {
70
- // Enhanced error handling with specific troubleshooting
71
- // Handle specific error cases
72
- if (typeof error === "object" && error !== null) {
73
- const errorObj = error;
74
- if (((_a = errorObj.error) === null || _a === void 0 ? void 0 : _a.code) === "API_KEY_CREATION_FAILED") {
75
- let detailedMessage = "Failed to create API key. This could be due to:\n";
76
- detailedMessage += "• Account limits or quota restrictions\n";
77
- detailedMessage += "• Insufficient permissions for API key creation\n";
78
- detailedMessage += "• Temporary server issues\n";
79
- detailedMessage += "• Billing or subscription issues\n\n";
80
- detailedMessage += "Troubleshooting steps:\n";
81
- detailedMessage += "1. Check if you have reached your API key limit\n";
82
- detailedMessage += "2. Verify your account has API key creation permissions\n";
83
- detailedMessage += "3. Check your billing status and subscription\n";
84
- detailedMessage += "4. Try again in a few minutes if this is a temporary issue\n";
85
- detailedMessage += "5. Contact support if the problem persists";
86
- throw new Error(detailedMessage);
87
- }
88
- if (((_b = errorObj.error) === null || _b === void 0 ? void 0 : _b.code) === "USER_NOT_FOUND") {
89
- 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");
90
- }
91
- if (((_c = errorObj.error) === null || _c === void 0 ? void 0 : _c.code) === "QUOTA_EXCEEDED") {
92
- throw new Error("You have reached your API key limit. Please delete existing keys or contact support to increase your quota.");
93
- }
94
- if (((_d = errorObj.error) === null || _d === void 0 ? void 0 : _d.code) === "INSUFFICIENT_PERMISSIONS") {
95
- throw new Error("Your account does not have permission to create API keys. Please contact your administrator.");
96
- }
97
- if (((_e = errorObj.error) === null || _e === void 0 ? void 0 : _e.code) === "BILLING_REQUIRED") {
98
- throw new Error("A valid billing method is required to create API keys. Please add a payment method.");
99
- }
100
- }
101
- throw new Error(JSON.stringify(error));
102
- }
103
- if (!data) {
104
- throw new Error("No data received from server");
105
- }
106
- return data;
29
+ async create(options) {
30
+ try {
31
+ // Validate input before sending request
32
+ if (!options.name || options.name.trim().length === 0) {
33
+ throw new Error('API key name is required and cannot be empty');
34
+ }
35
+ if (options.name.length > 100) {
36
+ throw new Error('API key name must be 100 characters or less');
37
+ }
38
+ if (options.description && options.description.length > 500) {
39
+ throw new Error('API key description must be 500 characters or less');
107
40
  }
108
- catch (error) {
109
- console.error("Failed to create API key:", error);
110
- // Add additional context for common issues
111
- if (error instanceof Error) {
112
- if (error.message.includes("ECONNREFUSED")) {
113
- throw new Error("Cannot connect to Berget API. Please check your internet connection.");
41
+ const { data, error } = await this.client.POST('/v1/api-keys', {
42
+ body: options,
43
+ });
44
+ if (error) {
45
+ // Enhanced error handling with specific troubleshooting
46
+ // Handle specific error cases
47
+ if (typeof error === 'object' && error !== null) {
48
+ const errorObject = error;
49
+ if (errorObject.error?.code === 'API_KEY_CREATION_FAILED') {
50
+ let detailedMessage = 'Failed to create API key. This could be due to:\n';
51
+ detailedMessage += '• Account limits or quota restrictions\n';
52
+ detailedMessage += '• Insufficient permissions for API key creation\n';
53
+ detailedMessage += '• Temporary server issues\n';
54
+ detailedMessage += '• Billing or subscription issues\n\n';
55
+ detailedMessage += 'Troubleshooting steps:\n';
56
+ detailedMessage += '1. Check if you have reached your API key limit\n';
57
+ detailedMessage += '2. Verify your account has API key creation permissions\n';
58
+ detailedMessage += '3. Check your billing status and subscription\n';
59
+ detailedMessage += '4. Try again in a few minutes if this is a temporary issue\n';
60
+ detailedMessage += '5. Contact support if the problem persists';
61
+ throw new Error(detailedMessage);
114
62
  }
115
- if (error.message.includes("ENOTFOUND")) {
116
- throw new Error("Cannot resolve Berget API hostname. Please check your DNS settings.");
63
+ if (errorObject.error?.code === 'USER_NOT_FOUND') {
64
+ 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');
117
65
  }
118
- if (error.message.includes("401") || error.message.includes("Unauthorized")) {
119
- throw new Error("Authentication failed. Please run `berget auth login` to log in again.");
66
+ if (errorObject.error?.code === 'QUOTA_EXCEEDED') {
67
+ throw new Error('You have reached your API key limit. Please delete existing keys or contact support to increase your quota.');
120
68
  }
121
- if (error.message.includes("403")) {
122
- throw new Error("Access forbidden. Your account may not have permission to create API keys.");
69
+ if (errorObject.error?.code === 'INSUFFICIENT_PERMISSIONS') {
70
+ throw new Error('Your account does not have permission to create API keys. Please contact your administrator.');
71
+ }
72
+ if (errorObject.error?.code === 'BILLING_REQUIRED') {
73
+ throw new Error('A valid billing method is required to create API keys. Please add a payment method.');
123
74
  }
124
75
  }
125
- throw error;
76
+ throw new Error(JSON.stringify(error));
77
+ }
78
+ if (!data) {
79
+ throw new Error('No data received from server');
126
80
  }
127
- });
81
+ return data;
82
+ }
83
+ catch (error) {
84
+ console.error('Failed to create API key:', error);
85
+ // Add additional context for common issues
86
+ if (error instanceof Error) {
87
+ if (error.message.includes('ECONNREFUSED')) {
88
+ throw new Error('Cannot connect to Berget API. Please check your internet connection.');
89
+ }
90
+ if (error.message.includes('ENOTFOUND')) {
91
+ throw new Error('Cannot resolve Berget API hostname. Please check your DNS settings.');
92
+ }
93
+ if (error.message.includes('401') || error.message.includes('Unauthorized')) {
94
+ throw new Error('Authentication failed. Please run `berget auth login` to log in again.');
95
+ }
96
+ if (error.message.includes('403')) {
97
+ throw new Error('Access forbidden. Your account may not have permission to create API keys.');
98
+ }
99
+ }
100
+ throw error;
101
+ }
128
102
  }
129
103
  /**
130
104
  * Delete an API key
131
105
  * Command: berget api-keys delete
132
106
  */
133
- delete(id) {
134
- return __awaiter(this, void 0, void 0, function* () {
135
- try {
136
- const { error } = yield this.client.DELETE("/v1/api-keys/{id}", {
137
- params: { path: { id } },
138
- });
139
- if (error)
140
- throw new Error(JSON.stringify(error));
141
- return true;
142
- }
143
- catch (error) {
144
- console.error("Failed to delete API key:", error);
145
- throw error;
146
- }
147
- });
107
+ async delete(id) {
108
+ try {
109
+ const { error } = await this.client.DELETE('/v1/api-keys/{id}', {
110
+ params: { path: { id } },
111
+ });
112
+ if (error)
113
+ throw new Error(JSON.stringify(error));
114
+ return true;
115
+ }
116
+ catch (error) {
117
+ console.error('Failed to delete API key:', error);
118
+ throw error;
119
+ }
148
120
  }
149
121
  /**
150
- * Rotate an API key
151
- * Command: berget api-keys rotate
122
+ * Get usage statistics for an API key
123
+ * Command: berget api-keys describe
152
124
  */
153
- rotate(id) {
154
- return __awaiter(this, void 0, void 0, function* () {
155
- try {
156
- const { data, error } = yield this.client.PUT("/v1/api-keys/{id}/rotate", {
157
- params: { path: { id } },
158
- });
159
- if (error)
160
- throw new Error(JSON.stringify(error));
161
- return data;
162
- }
163
- catch (error) {
164
- console.error("Failed to rotate API key:", error);
165
- throw error;
166
- }
167
- });
125
+ async describe(id) {
126
+ try {
127
+ const { data, error } = await this.client.GET('/v1/api-keys/{id}/usage', {
128
+ params: { path: { id } },
129
+ });
130
+ if (error)
131
+ throw new Error(JSON.stringify(error));
132
+ return data;
133
+ }
134
+ catch (error) {
135
+ console.error('Failed to get API key usage:', error);
136
+ throw error;
137
+ }
168
138
  }
169
139
  /**
170
- * Get usage statistics for an API key
171
- * Command: berget api-keys describe
140
+ * List all API keys
141
+ * Command: berget api-keys list
172
142
  */
173
- describe(id) {
174
- return __awaiter(this, void 0, void 0, function* () {
175
- try {
176
- const { data, error } = yield this.client.GET("/v1/api-keys/{id}/usage", {
177
- params: { path: { id } },
178
- });
179
- if (error)
180
- throw new Error(JSON.stringify(error));
181
- return data;
182
- }
183
- catch (error) {
184
- console.error("Failed to get API key usage:", error);
143
+ async list() {
144
+ try {
145
+ const { data, error } = await this.client.GET('/v1/api-keys');
146
+ if (error)
185
147
  throw error;
186
- }
187
- });
148
+ return data || [];
149
+ }
150
+ catch (error) {
151
+ (0, error_handler_1.handleError)('Failed to list API keys', error);
152
+ throw error;
153
+ }
154
+ }
155
+ /**
156
+ * Rotate an API key
157
+ * Command: berget api-keys rotate
158
+ */
159
+ async rotate(id) {
160
+ try {
161
+ const { data, error } = await this.client.PUT('/v1/api-keys/{id}/rotate', {
162
+ params: { path: { id } },
163
+ });
164
+ if (error)
165
+ throw new Error(JSON.stringify(error));
166
+ return data;
167
+ }
168
+ catch (error) {
169
+ console.error('Failed to rotate API key:', error);
170
+ throw error;
171
+ }
188
172
  }
189
173
  }
190
174
  exports.ApiKeyService = ApiKeyService;
191
- // Command group name for this service
192
- ApiKeyService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.API_KEYS;
193
- // Subcommands for this service
194
- ApiKeyService.COMMANDS = command_structure_1.SUBCOMMANDS.API_KEYS;
@@ -1,44 +1,31 @@
1
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
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
14
5
  Object.defineProperty(exports, "__esModule", { value: true });
15
6
  exports.AuthService = void 0;
16
- const client_1 = require("../client");
17
7
  const chalk_1 = __importDefault(require("chalk"));
18
- const error_handler_1 = require("../utils/error-handler");
8
+ const client_1 = require("../client");
19
9
  const command_structure_1 = require("../constants/command-structure");
10
+ const error_handler_1 = require("../utils/error-handler");
20
11
  const browser_auth_1 = require("./browser-auth");
21
12
  // Keycloak configuration based on environment
22
- const isStageMode = process.argv.includes("--stage");
23
- const isLocalMode = process.argv.includes("--local");
24
- const KEYCLOAK_URL = isStageMode || isLocalMode ? "https://keycloak.stage.berget.ai" : "https://keycloak.berget.ai";
25
- const KEYCLOAK_REALM = "berget";
26
- const KEYCLOAK_CLIENT_ID = "berget-code";
13
+ const isStageMode = process.argv.includes('--stage');
14
+ const isLocalMode = process.argv.includes('--local');
15
+ const KEYCLOAK_URL = isStageMode || isLocalMode ? 'https://keycloak.stage.berget.ai' : 'https://keycloak.berget.ai';
16
+ const KEYCLOAK_REALM = 'berget';
17
+ const KEYCLOAK_CLIENT_ID = 'berget-code';
27
18
  const CALLBACK_PORT = 8787;
28
- function makeBrowserAuth(debug) {
29
- return new browser_auth_1.BrowserAuth({
30
- keycloakUrl: KEYCLOAK_URL,
31
- realm: KEYCLOAK_REALM,
32
- clientId: KEYCLOAK_CLIENT_ID,
33
- callbackPort: CALLBACK_PORT,
34
- debug,
35
- });
36
- }
37
19
  /**
38
20
  * Service for authentication operations
39
21
  * Command group: auth
40
22
  */
41
23
  class AuthService {
24
+ // Command group name for this service
25
+ static COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.AUTH;
26
+ // Subcommands for this service
27
+ static COMMANDS = command_structure_1.SUBCOMMANDS.AUTH;
28
+ static instance;
42
29
  constructor() { }
43
30
  static getInstance() {
44
31
  if (!AuthService.instance) {
@@ -46,93 +33,92 @@ class AuthService {
46
33
  }
47
34
  return AuthService.instance;
48
35
  }
49
- whoami() {
50
- return __awaiter(this, void 0, void 0, function* () {
51
- try {
52
- // Create fresh client to ensure we have the latest token
53
- const client = (0, client_1.createAuthenticatedClient)();
54
- const { data: profile, error } = yield client.GET("/v1/users/me");
55
- if (error) {
56
- return null;
57
- }
58
- return profile;
59
- }
60
- catch (_a) {
61
- return null;
62
- }
63
- });
64
- }
65
36
  /**
66
37
  * Browser-based PKCE login for interactive CLI use.
67
38
  * Prints status to stdout/stderr. Use loginInteractive() when you need
68
39
  * a silent, UI-agnostic result (e.g. inside the setup wizard).
69
40
  */
70
- login() {
71
- return __awaiter(this, void 0, void 0, function* () {
41
+ async login() {
42
+ try {
43
+ (0, client_1.clearAuthToken)();
44
+ console.log(chalk_1.default.blue('Initiating login process...'));
45
+ const auth = makeBrowserAuth(process.argv.includes('--debug'));
46
+ const result = await auth.start();
47
+ if (!result.success) {
48
+ console.log(chalk_1.default.red(`\nAuthentication failed: ${result.error || 'Unknown error'}`));
49
+ return false;
50
+ }
51
+ (0, client_1.saveAuthToken)(result.accessToken, result.refreshToken, result.expiresIn);
52
+ if (process.argv.includes('--debug')) {
53
+ console.log(chalk_1.default.yellow('DEBUG: Token data received:'));
54
+ console.log(chalk_1.default.yellow(JSON.stringify({
55
+ expires_in: result.expiresIn,
56
+ }, null, 2)));
57
+ }
58
+ console.log(chalk_1.default.green('\n✓ Successfully logged in to Berget'));
72
59
  try {
73
- (0, client_1.clearAuthToken)();
74
- console.log(chalk_1.default.blue("Initiating login process..."));
75
- const auth = makeBrowserAuth(process.argv.includes("--debug"));
76
- const result = yield auth.start();
77
- if (!result.success) {
78
- console.log(chalk_1.default.red(`\nAuthentication failed: ${result.error || "Unknown error"}`));
79
- return false;
60
+ const profile = await this.whoami();
61
+ if (profile?.email) {
62
+ console.log(chalk_1.default.green(`Logged in as ${profile.name || profile.email}`));
80
63
  }
81
- (0, client_1.saveAuthToken)(result.accessToken, result.refreshToken, result.expiresIn);
82
- if (process.argv.includes("--debug")) {
83
- console.log(chalk_1.default.yellow("DEBUG: Token data received:"));
84
- console.log(chalk_1.default.yellow(JSON.stringify({
85
- expires_in: result.expiresIn,
86
- }, null, 2)));
87
- }
88
- console.log(chalk_1.default.green("\n✓ Successfully logged in to Berget"));
89
- try {
90
- const profile = yield this.whoami();
91
- if (profile === null || profile === void 0 ? void 0 : profile.email) {
92
- console.log(chalk_1.default.green(`Logged in as ${profile.name || profile.email}`));
93
- }
94
- }
95
- catch (_a) {
96
- // Ignore errors fetching profile
97
- }
98
- console.log(chalk_1.default.cyan("\nNext steps:"));
99
- console.log(chalk_1.default.cyan(" • Create an API key: berget api-keys create"));
100
- console.log(chalk_1.default.cyan(" • Setup OpenCode: berget code init"));
101
- return true;
102
64
  }
103
- catch (error) {
104
- (0, error_handler_1.handleError)("Login failed", error);
105
- return false;
65
+ catch {
66
+ // Ignore errors fetching profile
106
67
  }
107
- });
68
+ console.log(chalk_1.default.cyan('\nNext steps:'));
69
+ console.log(chalk_1.default.cyan(' • Create an API key: berget api-keys create'));
70
+ console.log(chalk_1.default.cyan(' • Setup OpenCode: berget code init'));
71
+ return true;
72
+ }
73
+ catch (error) {
74
+ (0, error_handler_1.handleError)('Login failed', error);
75
+ return false;
76
+ }
108
77
  }
109
78
  /**
110
79
  * Browser-based PKCE login for wizard / programmatic use.
111
80
  * Does NOT print to stdout — returns tokens so callers can display
112
81
  * their own UI (e.g. via clack/prompts).
113
82
  */
114
- loginInteractive() {
115
- return __awaiter(this, void 0, void 0, function* () {
116
- try {
117
- (0, client_1.clearAuthToken)();
118
- const auth = makeBrowserAuth(process.argv.includes("--debug"));
119
- const result = yield auth.start();
120
- if (result.success) {
121
- (0, client_1.saveAuthToken)(result.accessToken, result.refreshToken, result.expiresIn);
122
- }
123
- return result;
83
+ async loginInteractive() {
84
+ try {
85
+ (0, client_1.clearAuthToken)();
86
+ const auth = makeBrowserAuth(process.argv.includes('--debug'));
87
+ const result = await auth.start();
88
+ if (result.success) {
89
+ (0, client_1.saveAuthToken)(result.accessToken, result.refreshToken, result.expiresIn);
124
90
  }
125
- catch (error) {
126
- return {
127
- success: false,
128
- error: error instanceof Error ? error.message : String(error),
129
- };
91
+ return result;
92
+ }
93
+ catch (error) {
94
+ return {
95
+ error: error instanceof Error ? error.message : String(error),
96
+ success: false,
97
+ };
98
+ }
99
+ }
100
+ async whoami() {
101
+ try {
102
+ // Create fresh client to ensure we have the latest token
103
+ const client = (0, client_1.createAuthenticatedClient)();
104
+ const { data: profile, error } = await client.GET('/v1/users/me');
105
+ if (error) {
106
+ return null;
130
107
  }
131
- });
108
+ return profile;
109
+ }
110
+ catch {
111
+ return null;
112
+ }
132
113
  }
133
114
  }
134
115
  exports.AuthService = AuthService;
135
- // Command group name for this service
136
- AuthService.COMMAND_GROUP = command_structure_1.COMMAND_GROUPS.AUTH;
137
- // Subcommands for this service
138
- AuthService.COMMANDS = command_structure_1.SUBCOMMANDS.AUTH;
116
+ function makeBrowserAuth(debug) {
117
+ return new browser_auth_1.BrowserAuth({
118
+ callbackPort: CALLBACK_PORT,
119
+ clientId: KEYCLOAK_CLIENT_ID,
120
+ debug,
121
+ keycloakUrl: KEYCLOAK_URL,
122
+ realm: KEYCLOAK_REALM,
123
+ });
124
+ }