berget 2.2.5 → 2.2.7

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 (148) hide show
  1. package/.github/workflows/publish.yml +8 -8
  2. package/.github/workflows/test.yml +12 -6
  3. package/.husky/pre-commit +1 -0
  4. package/.prettierignore +15 -0
  5. package/.prettierrc +5 -3
  6. package/CONTRIBUTING.md +38 -0
  7. package/README.md +2 -148
  8. package/dist/index.js +21 -21
  9. package/dist/package.json +30 -2
  10. package/dist/src/agents/app.js +28 -0
  11. package/dist/src/agents/backend.js +25 -0
  12. package/dist/src/agents/devops.js +34 -0
  13. package/dist/src/agents/frontend.js +25 -0
  14. package/dist/src/agents/fullstack.js +25 -0
  15. package/dist/src/agents/index.js +61 -0
  16. package/dist/src/agents/quality.js +70 -0
  17. package/dist/src/agents/security.js +26 -0
  18. package/dist/src/agents/types.js +2 -0
  19. package/dist/src/client.js +54 -62
  20. package/dist/src/commands/api-keys.js +132 -140
  21. package/dist/src/commands/auth.js +9 -9
  22. package/dist/src/commands/autocomplete.js +9 -9
  23. package/dist/src/commands/billing.js +7 -9
  24. package/dist/src/commands/chat.js +90 -92
  25. package/dist/src/commands/clusters.js +12 -12
  26. package/dist/src/commands/code/__tests__/auth-sync.test.js +348 -0
  27. package/dist/src/commands/code/__tests__/fake-api-key-service.js +23 -0
  28. package/dist/src/commands/code/__tests__/fake-auth-service.js +55 -0
  29. package/dist/src/commands/code/__tests__/fake-command-runner.js +50 -0
  30. package/dist/src/commands/code/__tests__/fake-file-store.js +55 -0
  31. package/dist/src/commands/code/__tests__/fake-prompter.js +133 -0
  32. package/dist/src/commands/code/__tests__/setup-flow.test.js +505 -0
  33. package/dist/src/commands/code/adapters/clack-prompter.js +81 -0
  34. package/dist/src/commands/code/adapters/fs-file-store.js +80 -0
  35. package/dist/src/commands/code/adapters/spawn-command-runner.js +53 -0
  36. package/dist/src/commands/code/auth-sync.js +283 -0
  37. package/dist/src/commands/code/errors.js +27 -0
  38. package/dist/src/commands/code/ports/auth-services.js +2 -0
  39. package/dist/src/commands/code/ports/command-runner.js +2 -0
  40. package/dist/src/commands/code/ports/file-store.js +2 -0
  41. package/dist/src/commands/code/ports/prompter.js +2 -0
  42. package/dist/src/commands/code/setup.js +533 -0
  43. package/dist/src/commands/code.js +223 -779
  44. package/dist/src/commands/models.js +13 -15
  45. package/dist/src/commands/users.js +6 -8
  46. package/dist/src/constants/command-structure.js +116 -114
  47. package/dist/src/services/api-key-service.js +43 -48
  48. package/dist/src/services/auth-service.js +60 -299
  49. package/dist/src/services/browser-auth.js +278 -0
  50. package/dist/src/services/chat-service.js +78 -91
  51. package/dist/src/services/cluster-service.js +6 -6
  52. package/dist/src/services/collaborator-service.js +5 -8
  53. package/dist/src/services/flux-service.js +5 -8
  54. package/dist/src/services/helm-service.js +5 -8
  55. package/dist/src/services/kubectl-service.js +7 -10
  56. package/dist/src/utils/config-checker.js +5 -5
  57. package/dist/src/utils/config-loader.js +25 -25
  58. package/dist/src/utils/default-api-key.js +23 -23
  59. package/dist/src/utils/env-manager.js +7 -7
  60. package/dist/src/utils/error-handler.js +60 -61
  61. package/dist/src/utils/logger.js +7 -7
  62. package/dist/src/utils/markdown-renderer.js +2 -2
  63. package/dist/src/utils/opencode-validator.js +17 -20
  64. package/dist/src/utils/token-manager.js +38 -11
  65. package/dist/tests/commands/chat.test.js +24 -24
  66. package/dist/tests/commands/code.test.js +169 -138
  67. package/dist/tests/utils/config-loader.test.js +114 -114
  68. package/dist/tests/utils/env-manager.test.js +57 -57
  69. package/dist/tests/utils/opencode-validator.test.js +44 -43
  70. package/dist/vitest.config.js +1 -1
  71. package/eslint.config.mjs +47 -0
  72. package/index.ts +42 -48
  73. package/package.json +30 -2
  74. package/src/agents/app.ts +27 -0
  75. package/src/agents/backend.ts +24 -0
  76. package/src/agents/devops.ts +33 -0
  77. package/src/agents/frontend.ts +24 -0
  78. package/src/agents/fullstack.ts +24 -0
  79. package/src/agents/index.ts +71 -0
  80. package/src/agents/quality.ts +69 -0
  81. package/src/agents/security.ts +26 -0
  82. package/src/agents/types.ts +17 -0
  83. package/src/client.ts +125 -167
  84. package/src/commands/api-keys.ts +261 -358
  85. package/src/commands/auth.ts +24 -30
  86. package/src/commands/autocomplete.ts +12 -12
  87. package/src/commands/billing.ts +22 -27
  88. package/src/commands/chat.ts +230 -323
  89. package/src/commands/clusters.ts +33 -33
  90. package/src/commands/code/__tests__/auth-sync.test.ts +481 -0
  91. package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
  92. package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
  93. package/src/commands/code/__tests__/fake-command-runner.ts +44 -0
  94. package/src/commands/code/__tests__/fake-file-store.ts +44 -0
  95. package/src/commands/code/__tests__/fake-prompter.ts +121 -0
  96. package/src/commands/code/__tests__/setup-flow.test.ts +628 -0
  97. package/src/commands/code/adapters/clack-prompter.ts +55 -0
  98. package/src/commands/code/adapters/fs-file-store.ts +37 -0
  99. package/src/commands/code/adapters/spawn-command-runner.ts +40 -0
  100. package/src/commands/code/auth-sync.ts +329 -0
  101. package/src/commands/code/errors.ts +23 -0
  102. package/src/commands/code/ports/auth-services.ts +14 -0
  103. package/src/commands/code/ports/command-runner.ts +10 -0
  104. package/src/commands/code/ports/file-store.ts +7 -0
  105. package/src/commands/code/ports/prompter.ts +29 -0
  106. package/src/commands/code/setup.ts +630 -0
  107. package/src/commands/code.ts +335 -1074
  108. package/src/commands/index.ts +19 -19
  109. package/src/commands/models.ts +32 -37
  110. package/src/commands/users.ts +15 -22
  111. package/src/constants/command-structure.ts +120 -140
  112. package/src/services/api-key-service.ts +96 -113
  113. package/src/services/auth-service.ts +92 -339
  114. package/src/services/browser-auth.ts +296 -0
  115. package/src/services/chat-service.ts +246 -279
  116. package/src/services/cluster-service.ts +29 -32
  117. package/src/services/collaborator-service.ts +13 -18
  118. package/src/services/flux-service.ts +16 -18
  119. package/src/services/helm-service.ts +16 -18
  120. package/src/services/kubectl-service.ts +12 -14
  121. package/src/types/api.d.ts +924 -926
  122. package/src/types/json.d.ts +3 -3
  123. package/src/utils/config-checker.ts +10 -10
  124. package/src/utils/config-loader.ts +110 -127
  125. package/src/utils/default-api-key.ts +81 -93
  126. package/src/utils/env-manager.ts +36 -40
  127. package/src/utils/error-handler.ts +83 -78
  128. package/src/utils/logger.ts +41 -41
  129. package/src/utils/markdown-renderer.ts +11 -11
  130. package/src/utils/opencode-validator.ts +51 -56
  131. package/src/utils/token-manager.ts +84 -64
  132. package/templates/agents/app.md +23 -0
  133. package/templates/agents/backend.md +23 -0
  134. package/templates/agents/devops.md +30 -0
  135. package/templates/agents/frontend.md +25 -0
  136. package/templates/agents/fullstack.md +23 -0
  137. package/templates/agents/quality.md +69 -0
  138. package/templates/agents/security.md +21 -0
  139. package/tests/commands/chat.test.ts +60 -70
  140. package/tests/commands/code.test.ts +346 -345
  141. package/tests/utils/config-loader.test.ts +260 -260
  142. package/tests/utils/env-manager.test.ts +127 -134
  143. package/tests/utils/opencode-validator.test.ts +65 -69
  144. package/tsconfig.json +2 -2
  145. package/vitest.config.ts +3 -3
  146. package/AGENTS.md +0 -374
  147. package/TODO.md +0 -19
  148. package/opencode.json +0 -146
@@ -1,29 +1,29 @@
1
- import { createAuthenticatedClient } from '../client'
2
- import { handleError } from '../utils/error-handler'
3
- import { COMMAND_GROUPS, SUBCOMMANDS } from '../constants/command-structure'
1
+ import { createAuthenticatedClient } from "../client";
2
+ import { handleError } from "../utils/error-handler";
3
+ import { COMMAND_GROUPS, SUBCOMMANDS } from "../constants/command-structure";
4
4
 
5
5
  export interface ApiKey {
6
- id: number
7
- name: string
8
- description: string | null
9
- created: string
10
- lastUsed: string | null
11
- prefix: string
12
- active: boolean
13
- modified: string
6
+ id: number;
7
+ name: string;
8
+ description: string | null;
9
+ created: string;
10
+ lastUsed: string | null;
11
+ prefix: string;
12
+ active: boolean;
13
+ modified: string;
14
14
  }
15
15
 
16
16
  export interface CreateApiKeyOptions {
17
- name: string
18
- description?: string
17
+ name: string;
18
+ description?: string;
19
19
  }
20
20
 
21
21
  export interface ApiKeyResponse {
22
- id: number
23
- name: string
24
- description: string | null
25
- key: string
26
- created: string
22
+ id: number;
23
+ name: string;
24
+ description: string | null;
25
+ key: string;
26
+ created: string;
27
27
  }
28
28
 
29
29
  /**
@@ -31,22 +31,22 @@ export interface ApiKeyResponse {
31
31
  * Command group: api-keys
32
32
  */
33
33
  export class ApiKeyService {
34
- private static instance: ApiKeyService
35
- private client = createAuthenticatedClient()
34
+ private static instance: ApiKeyService;
35
+ private client = createAuthenticatedClient();
36
36
 
37
37
  // Command group name for this service
38
- public static readonly COMMAND_GROUP = COMMAND_GROUPS.API_KEYS
38
+ public static readonly COMMAND_GROUP = COMMAND_GROUPS.API_KEYS;
39
39
 
40
40
  // Subcommands for this service
41
- public static readonly COMMANDS = SUBCOMMANDS.API_KEYS
41
+ public static readonly COMMANDS = SUBCOMMANDS.API_KEYS;
42
42
 
43
43
  private constructor() {}
44
44
 
45
45
  public static getInstance(): ApiKeyService {
46
46
  if (!ApiKeyService.instance) {
47
- ApiKeyService.instance = new ApiKeyService()
47
+ ApiKeyService.instance = new ApiKeyService();
48
48
  }
49
- return ApiKeyService.instance
49
+ return ApiKeyService.instance;
50
50
  }
51
51
 
52
52
  /**
@@ -55,12 +55,12 @@ export class ApiKeyService {
55
55
  */
56
56
  public async list(): Promise<ApiKey[]> {
57
57
  try {
58
- const { data, error } = await this.client.GET('/v1/api-keys')
59
- if (error) throw error
60
- return data || []
58
+ const { data, error } = await this.client.GET("/v1/api-keys");
59
+ if (error) throw error;
60
+ return data || [];
61
61
  } catch (error) {
62
- handleError('Failed to list API keys', error)
63
- throw error
62
+ handleError("Failed to list API keys", error);
63
+ throw error;
64
64
  }
65
65
  }
66
66
 
@@ -72,116 +72,102 @@ export class ApiKeyService {
72
72
  try {
73
73
  // Validate input before sending request
74
74
  if (!options.name || options.name.trim().length === 0) {
75
- throw new Error('API key name is required and cannot be empty')
75
+ throw new Error("API key name is required and cannot be empty");
76
76
  }
77
77
 
78
78
  if (options.name.length > 100) {
79
- throw new Error('API key name must be 100 characters or less')
79
+ throw new Error("API key name must be 100 characters or less");
80
80
  }
81
81
 
82
82
  if (options.description && options.description.length > 500) {
83
- throw new Error('API key description must be 500 characters or less')
83
+ throw new Error("API key description must be 500 characters or less");
84
84
  }
85
85
 
86
- const { data, error } = await this.client.POST('/v1/api-keys', {
86
+ const { data, error } = await this.client.POST("/v1/api-keys", {
87
87
  body: options,
88
- })
88
+ });
89
89
 
90
90
  if (error) {
91
91
  // Enhanced error handling with specific troubleshooting
92
92
 
93
93
  // Handle specific error cases
94
- if (typeof error === 'object' && error !== null) {
95
- const errorObj = error as any
96
-
97
- if (errorObj.error?.code === 'API_KEY_CREATION_FAILED') {
98
- let detailedMessage =
99
- 'Failed to create API key. This could be due to:\n'
100
- detailedMessage += 'Account limits or quota restrictions\n'
101
- detailedMessage +=
102
- '• Insufficient permissions for API key creation\n'
103
- detailedMessage += '• Temporary server issues\n'
104
- detailedMessage += '• Billing or subscription issues\n\n'
105
- detailedMessage += 'Troubleshooting steps:\n'
106
- detailedMessage +=
107
- '1. Check if you have reached your API key limit\n'
108
- detailedMessage +=
109
- '2. Verify your account has API key creation permissions\n'
110
- detailedMessage += '3. Check your billing status and subscription\n'
111
- detailedMessage +=
112
- '4. Try again in a few minutes if this is a temporary issue\n'
113
- detailedMessage += '5. Contact support if the problem persists'
114
-
115
- throw new Error(detailedMessage)
94
+ if (typeof error === "object" && error !== null) {
95
+ const errorObj = error as any;
96
+
97
+ if (errorObj.error?.code === "API_KEY_CREATION_FAILED") {
98
+ let detailedMessage = "Failed to create API key. This could be due to:\n";
99
+ detailedMessage += "• Account limits or quota restrictions\n";
100
+ detailedMessage += "Insufficient permissions for API key creation\n";
101
+ detailedMessage += "• Temporary server issues\n";
102
+ detailedMessage += "• Billing or subscription issues\n\n";
103
+ detailedMessage += "Troubleshooting steps:\n";
104
+ detailedMessage += "1. Check if you have reached your API key limit\n";
105
+ detailedMessage += "2. Verify your account has API key creation permissions\n";
106
+ detailedMessage += "3. Check your billing status and subscription\n";
107
+ detailedMessage += "4. Try again in a few minutes if this is a temporary issue\n";
108
+ detailedMessage += "5. Contact support if the problem persists";
109
+
110
+ throw new Error(detailedMessage);
116
111
  }
117
112
 
118
- if (errorObj.error?.code === 'USER_NOT_FOUND') {
113
+ if (errorObj.error?.code === "USER_NOT_FOUND") {
119
114
  throw new Error(
120
- 'Your account is still being set up. Please wait a moment and try again.\n\nIf this issue persists, please contact support at support@berget.ai',
121
- )
115
+ "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"
116
+ );
122
117
  }
123
118
 
124
- if (errorObj.error?.code === 'QUOTA_EXCEEDED') {
119
+ if (errorObj.error?.code === "QUOTA_EXCEEDED") {
125
120
  throw new Error(
126
- 'You have reached your API key limit. Please delete existing keys or contact support to increase your quota.',
127
- )
121
+ "You have reached your API key limit. Please delete existing keys or contact support to increase your quota."
122
+ );
128
123
  }
129
124
 
130
- if (errorObj.error?.code === 'INSUFFICIENT_PERMISSIONS') {
125
+ if (errorObj.error?.code === "INSUFFICIENT_PERMISSIONS") {
131
126
  throw new Error(
132
- 'Your account does not have permission to create API keys. Please contact your administrator.',
133
- )
127
+ "Your account does not have permission to create API keys. Please contact your administrator."
128
+ );
134
129
  }
135
130
 
136
- if (errorObj.error?.code === 'BILLING_REQUIRED') {
131
+ if (errorObj.error?.code === "BILLING_REQUIRED") {
137
132
  throw new Error(
138
- 'A valid billing method is required to create API keys. Please add a payment method.',
139
- )
133
+ "A valid billing method is required to create API keys. Please add a payment method."
134
+ );
140
135
  }
141
136
  }
142
137
 
143
- throw new Error(JSON.stringify(error))
138
+ throw new Error(JSON.stringify(error));
144
139
  }
145
140
 
146
141
  if (!data) {
147
- throw new Error('No data received from server')
142
+ throw new Error("No data received from server");
148
143
  }
149
144
 
150
- return data
145
+ return data;
151
146
  } catch (error) {
152
- console.error('Failed to create API key:', error)
147
+ console.error("Failed to create API key:", error);
153
148
 
154
149
  // Add additional context for common issues
155
150
  if (error instanceof Error) {
156
- if (error.message.includes('ECONNREFUSED')) {
157
- throw new Error(
158
- 'Cannot connect to Berget API. Please check your internet connection.',
159
- )
151
+ if (error.message.includes("ECONNREFUSED")) {
152
+ throw new Error("Cannot connect to Berget API. Please check your internet connection.");
160
153
  }
161
154
 
162
- if (error.message.includes('ENOTFOUND')) {
163
- throw new Error(
164
- 'Cannot resolve Berget API hostname. Please check your DNS settings.',
165
- )
155
+ if (error.message.includes("ENOTFOUND")) {
156
+ throw new Error("Cannot resolve Berget API hostname. Please check your DNS settings.");
166
157
  }
167
158
 
168
- if (
169
- error.message.includes('401') ||
170
- error.message.includes('Unauthorized')
171
- ) {
172
- throw new Error(
173
- 'Authentication failed. Please run `berget auth login` to log in again.',
174
- )
159
+ if (error.message.includes("401") || error.message.includes("Unauthorized")) {
160
+ throw new Error("Authentication failed. Please run `berget auth login` to log in again.");
175
161
  }
176
162
 
177
- if (error.message.includes('403')) {
163
+ if (error.message.includes("403")) {
178
164
  throw new Error(
179
- 'Access forbidden. Your account may not have permission to create API keys.',
180
- )
165
+ "Access forbidden. Your account may not have permission to create API keys."
166
+ );
181
167
  }
182
168
  }
183
169
 
184
- throw error
170
+ throw error;
185
171
  }
186
172
  }
187
173
 
@@ -191,14 +177,14 @@ export class ApiKeyService {
191
177
  */
192
178
  public async delete(id: string): Promise<boolean> {
193
179
  try {
194
- const { error } = await this.client.DELETE('/v1/api-keys/{id}', {
180
+ const { error } = await this.client.DELETE("/v1/api-keys/{id}", {
195
181
  params: { path: { id } },
196
- })
197
- if (error) throw new Error(JSON.stringify(error))
198
- return true
182
+ });
183
+ if (error) throw new Error(JSON.stringify(error));
184
+ return true;
199
185
  } catch (error) {
200
- console.error('Failed to delete API key:', error)
201
- throw error
186
+ console.error("Failed to delete API key:", error);
187
+ throw error;
202
188
  }
203
189
  }
204
190
 
@@ -208,17 +194,14 @@ export class ApiKeyService {
208
194
  */
209
195
  public async rotate(id: string): Promise<ApiKeyResponse> {
210
196
  try {
211
- const { data, error } = await this.client.PUT(
212
- '/v1/api-keys/{id}/rotate',
213
- {
214
- params: { path: { id } },
215
- },
216
- )
217
- if (error) throw new Error(JSON.stringify(error))
218
- return data!
197
+ const { data, error } = await this.client.PUT("/v1/api-keys/{id}/rotate", {
198
+ params: { path: { id } },
199
+ });
200
+ if (error) throw new Error(JSON.stringify(error));
201
+ return data!;
219
202
  } catch (error) {
220
- console.error('Failed to rotate API key:', error)
221
- throw error
203
+ console.error("Failed to rotate API key:", error);
204
+ throw error;
222
205
  }
223
206
  }
224
207
 
@@ -228,14 +211,14 @@ export class ApiKeyService {
228
211
  */
229
212
  public async describe(id: string): Promise<any> {
230
213
  try {
231
- const { data, error } = await this.client.GET('/v1/api-keys/{id}/usage', {
214
+ const { data, error } = await this.client.GET("/v1/api-keys/{id}/usage", {
232
215
  params: { path: { id } },
233
- })
234
- if (error) throw new Error(JSON.stringify(error))
235
- return data
216
+ });
217
+ if (error) throw new Error(JSON.stringify(error));
218
+ return data;
236
219
  } catch (error) {
237
- console.error('Failed to get API key usage:', error)
238
- throw error
220
+ console.error("Failed to get API key usage:", error);
221
+ throw error;
239
222
  }
240
223
  }
241
224
  }