berget 2.2.7 → 2.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +6 -6
- package/.github/workflows/test.yml +1 -1
- package/.prettierrc +5 -3
- package/dist/index.js +24 -25
- package/dist/package.json +5 -3
- package/dist/src/agents/app.js +8 -8
- package/dist/src/agents/backend.js +3 -3
- package/dist/src/agents/devops.js +8 -8
- package/dist/src/agents/frontend.js +3 -3
- package/dist/src/agents/fullstack.js +3 -3
- package/dist/src/agents/index.js +18 -18
- package/dist/src/agents/quality.js +8 -8
- package/dist/src/agents/security.js +8 -8
- package/dist/src/client.js +115 -127
- package/dist/src/commands/api-keys.js +195 -202
- package/dist/src/commands/auth.js +16 -25
- package/dist/src/commands/autocomplete.js +8 -8
- package/dist/src/commands/billing.js +10 -19
- package/dist/src/commands/chat.js +139 -170
- package/dist/src/commands/clusters.js +21 -30
- package/dist/src/commands/code/__tests__/auth-sync.test.js +189 -186
- package/dist/src/commands/code/__tests__/fake-api-key-service.js +3 -13
- package/dist/src/commands/code/__tests__/fake-auth-service.js +21 -29
- package/dist/src/commands/code/__tests__/fake-command-runner.js +22 -33
- package/dist/src/commands/code/__tests__/fake-file-store.js +19 -41
- package/dist/src/commands/code/__tests__/fake-prompter.js +81 -97
- package/dist/src/commands/code/__tests__/setup-flow.test.js +295 -295
- package/dist/src/commands/code/adapters/clack-prompter.js +15 -32
- package/dist/src/commands/code/adapters/fs-file-store.js +25 -44
- package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -41
- package/dist/src/commands/code/auth-sync.js +215 -228
- package/dist/src/commands/code/errors.js +15 -12
- package/dist/src/commands/code/setup.js +390 -425
- package/dist/src/commands/code.js +279 -294
- package/dist/src/commands/index.js +5 -5
- package/dist/src/commands/models.js +16 -25
- package/dist/src/commands/users.js +9 -18
- package/dist/src/constants/command-structure.js +138 -138
- package/dist/src/services/api-key-service.js +132 -152
- package/dist/src/services/auth-service.js +81 -95
- package/dist/src/services/browser-auth.js +121 -131
- package/dist/src/services/chat-service.js +369 -386
- package/dist/src/services/cluster-service.js +47 -62
- package/dist/src/services/collaborator-service.js +9 -21
- package/dist/src/services/flux-service.js +13 -25
- package/dist/src/services/helm-service.js +9 -21
- package/dist/src/services/kubectl-service.js +15 -29
- package/dist/src/utils/config-checker.js +7 -7
- package/dist/src/utils/config-loader.js +109 -109
- package/dist/src/utils/default-api-key.js +129 -139
- package/dist/src/utils/env-manager.js +55 -66
- package/dist/src/utils/error-handler.js +62 -62
- package/dist/src/utils/logger.js +74 -67
- package/dist/src/utils/markdown-renderer.js +28 -28
- package/dist/src/utils/opencode-validator.js +67 -69
- package/dist/src/utils/token-manager.js +67 -65
- package/dist/tests/commands/chat.test.js +30 -39
- package/dist/tests/commands/code.test.js +186 -195
- package/dist/tests/utils/config-loader.test.js +107 -107
- package/dist/tests/utils/env-manager.test.js +81 -90
- package/dist/tests/utils/opencode-validator.test.js +42 -41
- package/dist/vitest.config.js +1 -1
- package/eslint.config.mjs +50 -30
- package/index.ts +30 -31
- package/package.json +5 -3
- package/src/agents/app.ts +9 -9
- package/src/agents/backend.ts +4 -4
- package/src/agents/devops.ts +9 -9
- package/src/agents/frontend.ts +4 -4
- package/src/agents/fullstack.ts +4 -4
- package/src/agents/index.ts +27 -25
- package/src/agents/quality.ts +9 -9
- package/src/agents/security.ts +9 -9
- package/src/agents/types.ts +10 -10
- package/src/client.ts +85 -77
- package/src/commands/api-keys.ts +190 -185
- package/src/commands/auth.ts +15 -14
- package/src/commands/autocomplete.ts +10 -10
- package/src/commands/billing.ts +13 -12
- package/src/commands/chat.ts +145 -142
- package/src/commands/clusters.ts +20 -19
- package/src/commands/code/__tests__/auth-sync.test.ts +176 -175
- package/src/commands/code/__tests__/fake-api-key-service.ts +2 -2
- package/src/commands/code/__tests__/fake-auth-service.ts +18 -18
- package/src/commands/code/__tests__/fake-command-runner.ts +28 -22
- package/src/commands/code/__tests__/fake-file-store.ts +15 -15
- package/src/commands/code/__tests__/fake-prompter.ts +86 -85
- package/src/commands/code/__tests__/setup-flow.test.ts +253 -251
- package/src/commands/code/adapters/clack-prompter.ts +32 -30
- package/src/commands/code/adapters/fs-file-store.ts +18 -17
- package/src/commands/code/adapters/spawn-command-runner.ts +20 -15
- package/src/commands/code/auth-sync.ts +210 -210
- package/src/commands/code/errors.ts +11 -11
- package/src/commands/code/ports/auth-services.ts +7 -7
- package/src/commands/code/ports/command-runner.ts +2 -2
- package/src/commands/code/ports/file-store.ts +3 -3
- package/src/commands/code/ports/prompter.ts +13 -13
- package/src/commands/code/setup.ts +408 -406
- package/src/commands/code.ts +288 -287
- package/src/commands/index.ts +11 -10
- package/src/commands/models.ts +19 -18
- package/src/commands/users.ts +11 -10
- package/src/constants/command-structure.ts +159 -159
- package/src/services/api-key-service.ts +85 -85
- package/src/services/auth-service.ts +55 -54
- package/src/services/browser-auth.ts +62 -62
- package/src/services/chat-service.ts +169 -170
- package/src/services/cluster-service.ts +28 -28
- package/src/services/collaborator-service.ts +6 -6
- package/src/services/flux-service.ts +17 -17
- package/src/services/helm-service.ts +11 -11
- package/src/services/kubectl-service.ts +12 -12
- package/src/types/api.d.ts +1933 -1933
- package/src/types/json.d.ts +1 -1
- package/src/utils/config-checker.ts +6 -6
- package/src/utils/config-loader.ts +130 -129
- package/src/utils/default-api-key.ts +81 -80
- package/src/utils/env-manager.ts +37 -37
- package/src/utils/error-handler.ts +64 -64
- package/src/utils/logger.ts +72 -66
- package/src/utils/markdown-renderer.ts +28 -28
- package/src/utils/opencode-validator.ts +72 -71
- package/src/utils/token-manager.ts +69 -68
- package/tests/commands/chat.test.ts +32 -31
- package/tests/commands/code.test.ts +182 -181
- package/tests/utils/config-loader.test.ts +111 -110
- package/tests/utils/env-manager.test.ts +83 -79
- package/tests/utils/opencode-validator.test.ts +43 -42
- package/tsconfig.json +2 -1
- package/vitest.config.ts +2 -2
package/src/client.ts
CHANGED
|
@@ -1,40 +1,44 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import createClient from 'openapi-fetch';
|
|
3
|
+
|
|
4
|
+
import type { paths } from './types/api';
|
|
5
|
+
|
|
6
|
+
import { logger } from './utils/logger';
|
|
7
|
+
import { TokenManager } from './utils/token-manager';
|
|
8
|
+
|
|
9
|
+
type ApiMethod = (...args: unknown[]) => Promise<any>;
|
|
6
10
|
|
|
7
11
|
// API Base URL
|
|
8
12
|
// Use --local flag to test against local API
|
|
9
13
|
// Use --stage flag to test against stage API
|
|
10
|
-
const isLocalMode = process.argv.includes(
|
|
11
|
-
const isStageMode = process.argv.includes(
|
|
14
|
+
const isLocalMode = process.argv.includes('--local');
|
|
15
|
+
const isStageMode = process.argv.includes('--stage');
|
|
12
16
|
|
|
13
17
|
export const API_BASE_URL =
|
|
14
18
|
process.env.BERGET_API_URL ||
|
|
15
19
|
(isLocalMode
|
|
16
|
-
?
|
|
20
|
+
? 'http://localhost:3000'
|
|
17
21
|
: isStageMode
|
|
18
|
-
?
|
|
19
|
-
:
|
|
22
|
+
? 'https://api.stage.berget.ai'
|
|
23
|
+
: 'https://api.berget.ai'); // production default
|
|
20
24
|
|
|
21
25
|
if (isLocalMode && !process.env.BERGET_API_URL) {
|
|
22
|
-
logger.debug(
|
|
26
|
+
logger.debug('Using local API endpoint: http://localhost:3000');
|
|
23
27
|
} else if (isStageMode && !process.env.BERGET_API_URL) {
|
|
24
|
-
logger.debug(
|
|
28
|
+
logger.debug('Using stage API endpoint: https://api.stage.berget.ai');
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
// Create a typed client for the Berget API
|
|
28
32
|
export const apiClient = createClient<paths>({
|
|
29
33
|
baseUrl: API_BASE_URL,
|
|
30
34
|
headers: {
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
Accept: 'application/json',
|
|
36
|
+
'Content-Type': 'application/json',
|
|
33
37
|
},
|
|
34
38
|
});
|
|
35
39
|
|
|
36
40
|
// Authentication functions
|
|
37
|
-
export const getAuthToken = ():
|
|
41
|
+
export const getAuthToken = (): null | string => {
|
|
38
42
|
const tokenManager = TokenManager.getInstance();
|
|
39
43
|
return tokenManager.getAccessToken();
|
|
40
44
|
};
|
|
@@ -42,7 +46,7 @@ export const getAuthToken = (): string | null => {
|
|
|
42
46
|
export const saveAuthToken = (
|
|
43
47
|
accessToken: string,
|
|
44
48
|
refreshToken: string,
|
|
45
|
-
expiresIn: number = 3600
|
|
49
|
+
expiresIn: number = 3600,
|
|
46
50
|
): void => {
|
|
47
51
|
const tokenManager = TokenManager.getInstance();
|
|
48
52
|
tokenManager.setTokens(accessToken, refreshToken, expiresIn);
|
|
@@ -58,7 +62,7 @@ export const createAuthenticatedClient = () => {
|
|
|
58
62
|
const tokenManager = TokenManager.getInstance();
|
|
59
63
|
|
|
60
64
|
if (!tokenManager.getAccessToken()) {
|
|
61
|
-
logger.debug(
|
|
65
|
+
logger.debug('No authentication token found. Please run `berget auth login` first.');
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
// Create the base client
|
|
@@ -66,46 +70,46 @@ export const createAuthenticatedClient = () => {
|
|
|
66
70
|
baseUrl: API_BASE_URL,
|
|
67
71
|
headers: tokenManager.getAccessToken()
|
|
68
72
|
? {
|
|
73
|
+
Accept: 'application/json',
|
|
69
74
|
Authorization: `Bearer ${tokenManager.getAccessToken()}`,
|
|
70
|
-
|
|
71
|
-
Accept: "application/json",
|
|
75
|
+
'Content-Type': 'application/json',
|
|
72
76
|
}
|
|
73
77
|
: {
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
Accept: 'application/json',
|
|
79
|
+
'Content-Type': 'application/json',
|
|
76
80
|
},
|
|
77
81
|
});
|
|
78
82
|
|
|
79
83
|
// Wrap the client to handle token refresh
|
|
80
84
|
return new Proxy(client, {
|
|
81
|
-
get(target,
|
|
85
|
+
get(target, property: string | symbol) {
|
|
82
86
|
// For HTTP methods (GET, POST, etc.), add token refresh logic
|
|
83
87
|
if (
|
|
84
|
-
typeof target[
|
|
85
|
-
[
|
|
88
|
+
typeof target[property as keyof typeof target] === 'function' &&
|
|
89
|
+
['DELETE', 'GET', 'PATCH', 'POST', 'PUT'].includes(String(property))
|
|
86
90
|
) {
|
|
87
|
-
return async (...
|
|
91
|
+
return async (...arguments_: any[]) => {
|
|
88
92
|
// Check if token is expired before making the request
|
|
89
93
|
if (tokenManager.isTokenExpired() && tokenManager.getRefreshToken()) {
|
|
90
94
|
await refreshAccessToken(tokenManager);
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
// Update the Authorization header with the current token
|
|
94
|
-
if (!
|
|
95
|
-
if (!
|
|
96
|
-
if (!
|
|
97
|
-
|
|
98
|
+
if (!arguments_[1]?.headers?.Authorization && tokenManager.getAccessToken()) {
|
|
99
|
+
if (!arguments_[1]) arguments_[1] = {};
|
|
100
|
+
if (!arguments_[1].headers) arguments_[1].headers = {};
|
|
101
|
+
arguments_[1].headers.Authorization = `Bearer ${tokenManager.getAccessToken()}`;
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
// Make the original request
|
|
101
105
|
let result;
|
|
102
106
|
try {
|
|
103
|
-
result = await (target[
|
|
107
|
+
result = await (target[property as keyof typeof target] as ApiMethod)(...arguments_);
|
|
104
108
|
} catch (requestError) {
|
|
105
109
|
logger.debug(
|
|
106
110
|
`Request error: ${
|
|
107
111
|
requestError instanceof Error ? requestError.message : String(requestError)
|
|
108
|
-
}
|
|
112
|
+
}`,
|
|
109
113
|
);
|
|
110
114
|
return {
|
|
111
115
|
error: {
|
|
@@ -123,63 +127,63 @@ export const createAuthenticatedClient = () => {
|
|
|
123
127
|
|
|
124
128
|
try {
|
|
125
129
|
// Standard 401 Unauthorized
|
|
126
|
-
if (typeof result.error ===
|
|
130
|
+
if (typeof result.error === 'object' && result.error.status === 401) {
|
|
127
131
|
isAuthError = true;
|
|
128
132
|
}
|
|
129
133
|
// OAuth specific errors
|
|
130
134
|
else if (
|
|
131
135
|
result.error.error &&
|
|
132
|
-
(result.error.error.code ===
|
|
133
|
-
result.error.error.code ===
|
|
134
|
-
result.error.error.message ===
|
|
135
|
-
result.error.error.message?.toLowerCase().includes(
|
|
136
|
-
result.error.error.message?.toLowerCase().includes(
|
|
136
|
+
(result.error.error.code === 'invalid_token' ||
|
|
137
|
+
result.error.error.code === 'token_expired' ||
|
|
138
|
+
result.error.error.message === 'Invalid API key' ||
|
|
139
|
+
result.error.error.message?.toLowerCase().includes('token') ||
|
|
140
|
+
result.error.error.message?.toLowerCase().includes('unauthorized'))
|
|
137
141
|
) {
|
|
138
142
|
isAuthError = true;
|
|
139
143
|
}
|
|
140
144
|
// Message-based detection as fallback
|
|
141
145
|
else if (
|
|
142
|
-
typeof result.error ===
|
|
143
|
-
(result.error.toLowerCase().includes(
|
|
144
|
-
result.error.toLowerCase().includes(
|
|
145
|
-
result.error.toLowerCase().includes(
|
|
146
|
+
typeof result.error === 'string' &&
|
|
147
|
+
(result.error.toLowerCase().includes('unauthorized') ||
|
|
148
|
+
result.error.toLowerCase().includes('token') ||
|
|
149
|
+
result.error.toLowerCase().includes('auth'))
|
|
146
150
|
) {
|
|
147
151
|
isAuthError = true;
|
|
148
152
|
}
|
|
149
153
|
} catch {
|
|
150
154
|
// If we can't parse the error structure, do a simple string check
|
|
151
|
-
const
|
|
155
|
+
const errorString = String(result.error);
|
|
152
156
|
if (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
157
|
+
errorString.toLowerCase().includes('unauthorized') ||
|
|
158
|
+
errorString.toLowerCase().includes('token') ||
|
|
159
|
+
errorString.toLowerCase().includes('auth')
|
|
156
160
|
) {
|
|
157
161
|
isAuthError = true;
|
|
158
162
|
}
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
if (isAuthError && tokenManager.getRefreshToken()) {
|
|
162
|
-
logger.debug(
|
|
166
|
+
logger.debug('Auth error detected, attempting token refresh');
|
|
163
167
|
logger.debug(`Error details: ${JSON.stringify(result.error, null, 2)}`);
|
|
164
168
|
|
|
165
169
|
const refreshed = await refreshAccessToken(tokenManager);
|
|
166
170
|
if (refreshed) {
|
|
167
|
-
logger.debug(
|
|
171
|
+
logger.debug('Token refreshed successfully, retrying request');
|
|
168
172
|
|
|
169
173
|
// Update the Authorization header with the new token
|
|
170
|
-
if (!
|
|
171
|
-
if (!
|
|
172
|
-
|
|
174
|
+
if (!arguments_[1]) arguments_[1] = {};
|
|
175
|
+
if (!arguments_[1].headers) arguments_[1].headers = {};
|
|
176
|
+
arguments_[1].headers.Authorization = `Bearer ${tokenManager.getAccessToken()}`;
|
|
173
177
|
|
|
174
178
|
// Retry the request
|
|
175
|
-
return await (target[
|
|
179
|
+
return await (target[property as keyof typeof target] as ApiMethod)(...arguments_);
|
|
176
180
|
} else {
|
|
177
|
-
logger.debug(
|
|
181
|
+
logger.debug('Token refresh failed');
|
|
178
182
|
|
|
179
183
|
// Add a more helpful error message for users
|
|
180
|
-
if (typeof result.error ===
|
|
184
|
+
if (typeof result.error === 'object') {
|
|
181
185
|
result.error.userMessage =
|
|
182
|
-
|
|
186
|
+
'Your session has expired. Please run `berget auth login` to log in again.';
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
189
|
}
|
|
@@ -190,16 +194,16 @@ export const createAuthenticatedClient = () => {
|
|
|
190
194
|
}
|
|
191
195
|
|
|
192
196
|
// For other properties, just return the original
|
|
193
|
-
return target[
|
|
197
|
+
return target[property as keyof typeof target];
|
|
194
198
|
},
|
|
195
199
|
});
|
|
196
200
|
};
|
|
197
201
|
|
|
198
202
|
// Keycloak configuration for token refresh (must match auth-service.ts)
|
|
199
203
|
const KEYCLOAK_URL =
|
|
200
|
-
isStageMode || isLocalMode ?
|
|
201
|
-
const KEYCLOAK_REALM =
|
|
202
|
-
const KEYCLOAK_CLIENT_ID =
|
|
204
|
+
isStageMode || isLocalMode ? 'https://keycloak.stage.berget.ai' : 'https://keycloak.berget.ai';
|
|
205
|
+
const KEYCLOAK_REALM = 'berget';
|
|
206
|
+
const KEYCLOAK_CLIENT_ID = 'berget-code';
|
|
203
207
|
|
|
204
208
|
// Helper function to refresh the access token
|
|
205
209
|
async function refreshAccessToken(tokenManager: TokenManager): Promise<boolean> {
|
|
@@ -207,23 +211,23 @@ async function refreshAccessToken(tokenManager: TokenManager): Promise<boolean>
|
|
|
207
211
|
const refreshToken = tokenManager.getRefreshToken();
|
|
208
212
|
if (!refreshToken) return false;
|
|
209
213
|
|
|
210
|
-
logger.debug(
|
|
214
|
+
logger.debug('Attempting to refresh access token');
|
|
211
215
|
|
|
212
216
|
// Refresh directly against Keycloak (berget-code is a public PKCE client)
|
|
213
217
|
try {
|
|
214
218
|
const response = await fetch(
|
|
215
219
|
`${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`,
|
|
216
220
|
{
|
|
217
|
-
method: "POST",
|
|
218
|
-
headers: {
|
|
219
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
220
|
-
},
|
|
221
221
|
body: new URLSearchParams({
|
|
222
|
-
grant_type: "refresh_token",
|
|
223
222
|
client_id: KEYCLOAK_CLIENT_ID,
|
|
223
|
+
grant_type: 'refresh_token',
|
|
224
224
|
refresh_token: refreshToken,
|
|
225
225
|
}),
|
|
226
|
-
|
|
226
|
+
headers: {
|
|
227
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
228
|
+
},
|
|
229
|
+
method: 'POST',
|
|
230
|
+
},
|
|
227
231
|
);
|
|
228
232
|
|
|
229
233
|
// Handle HTTP errors
|
|
@@ -233,34 +237,38 @@ async function refreshAccessToken(tokenManager: TokenManager): Promise<boolean>
|
|
|
233
237
|
// Check if the refresh token itself is expired or invalid
|
|
234
238
|
if (response.status === 401 || response.status === 403) {
|
|
235
239
|
console.warn(
|
|
236
|
-
chalk.yellow(
|
|
240
|
+
chalk.yellow('Your refresh token has expired. Please run `berget auth login` again.'),
|
|
237
241
|
);
|
|
238
242
|
// Clear tokens if unauthorized - they're invalid
|
|
239
243
|
tokenManager.clearTokens();
|
|
240
244
|
} else {
|
|
241
245
|
console.warn(
|
|
242
|
-
chalk.yellow(`Failed to refresh token: ${response.status} ${response.statusText}`)
|
|
246
|
+
chalk.yellow(`Failed to refresh token: ${response.status} ${response.statusText}`),
|
|
243
247
|
);
|
|
244
248
|
}
|
|
245
249
|
return false;
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
// Parse the response
|
|
249
|
-
const contentType = response.headers.get(
|
|
250
|
-
if (!contentType || !contentType.includes(
|
|
253
|
+
const contentType = response.headers.get('content-type');
|
|
254
|
+
if (!contentType || !contentType.includes('application/json')) {
|
|
251
255
|
console.warn(chalk.yellow(`Unexpected content type in response: ${contentType}`));
|
|
252
256
|
return false;
|
|
253
257
|
}
|
|
254
258
|
|
|
255
|
-
const data = await response.json()
|
|
259
|
+
const data = (await response.json()) as {
|
|
260
|
+
expires_in?: number;
|
|
261
|
+
refresh_token?: string;
|
|
262
|
+
token: string;
|
|
263
|
+
};
|
|
256
264
|
|
|
257
265
|
// Validate the response data
|
|
258
266
|
if (!data || !data.token) {
|
|
259
|
-
console.warn(chalk.yellow(
|
|
267
|
+
console.warn(chalk.yellow('Invalid token response. Please run `berget auth login` again.'));
|
|
260
268
|
return false;
|
|
261
269
|
}
|
|
262
270
|
|
|
263
|
-
logger.debug(
|
|
271
|
+
logger.debug('Token refreshed successfully');
|
|
264
272
|
|
|
265
273
|
// Update the token
|
|
266
274
|
tokenManager.updateAccessToken(data.token, data.expires_in || 3600);
|
|
@@ -268,15 +276,15 @@ async function refreshAccessToken(tokenManager: TokenManager): Promise<boolean>
|
|
|
268
276
|
// If a new refresh token was provided, update that too
|
|
269
277
|
if (data.refresh_token) {
|
|
270
278
|
tokenManager.setTokens(data.token, data.refresh_token, data.expires_in || 3600);
|
|
271
|
-
logger.debug(
|
|
279
|
+
logger.debug('Refresh token also updated');
|
|
272
280
|
}
|
|
273
281
|
} catch (fetchError) {
|
|
274
282
|
console.warn(
|
|
275
283
|
chalk.yellow(
|
|
276
284
|
`Failed to refresh token: ${
|
|
277
285
|
fetchError instanceof Error ? fetchError.message : String(fetchError)
|
|
278
|
-
}
|
|
279
|
-
)
|
|
286
|
+
}`,
|
|
287
|
+
),
|
|
280
288
|
);
|
|
281
289
|
return false;
|
|
282
290
|
}
|
|
@@ -287,8 +295,8 @@ async function refreshAccessToken(tokenManager: TokenManager): Promise<boolean>
|
|
|
287
295
|
chalk.yellow(
|
|
288
296
|
`Failed to refresh authentication token: ${
|
|
289
297
|
error instanceof Error ? error.message : String(error)
|
|
290
|
-
}
|
|
291
|
-
)
|
|
298
|
+
}`,
|
|
299
|
+
),
|
|
292
300
|
);
|
|
293
301
|
return false;
|
|
294
302
|
}
|