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
@@ -3,28 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.fixOpenCodeConfig = exports.validateOpenCodeConfig = void 0;
6
+ exports.validateOpenCodeConfig = exports.fixOpenCodeConfig = void 0;
7
7
  const ajv_1 = __importDefault(require("ajv"));
8
8
  const ajv_formats_1 = __importDefault(require("ajv-formats"));
9
- const fs_1 = require("fs");
10
- const path_1 = require("path");
11
- const path_2 = require("path");
9
+ const node_fs_1 = require("node:fs");
10
+ const node_path_1 = require("node:path");
11
+ const node_path_2 = require("node:path");
12
12
  // Load the official OpenCode JSON Schema
13
- const __dirname = (0, path_2.dirname)(__filename);
14
- const schemaPath = (0, path_1.join)(__dirname, "..", "schemas", "opencode-schema.json");
13
+ const __dirname = (0, node_path_2.dirname)(__filename);
14
+ const schemaPath = (0, node_path_1.join)(__dirname, '..', 'schemas', 'opencode-schema.json');
15
15
  let ajv;
16
16
  let openCodeSchema;
17
17
  let validateFunction;
18
18
  try {
19
- const schemaContent = (0, fs_1.readFileSync)(schemaPath, "utf-8");
19
+ const schemaContent = (0, node_fs_1.readFileSync)(schemaPath, 'utf-8');
20
20
  openCodeSchema = JSON.parse(schemaContent);
21
21
  // Initialize AJV with formats and options
22
22
  ajv = new ajv_1.default({
23
23
  allErrors: true,
24
- verbose: true,
25
- strict: false,
26
24
  allowUnionTypes: true,
27
25
  removeAdditional: false,
26
+ strict: false,
27
+ verbose: true,
28
28
  });
29
29
  // Add JSON Schema formats
30
30
  (0, ajv_formats_1.default)(ajv);
@@ -32,83 +32,54 @@ try {
32
32
  validateFunction = ajv.compile(openCodeSchema);
33
33
  }
34
34
  catch (error) {
35
- console.error("Failed to load OpenCode schema:", error);
36
- throw new Error("Could not initialize OpenCode validator");
35
+ console.error('Failed to load OpenCode schema:', error);
36
+ throw new Error('Could not initialize OpenCode validator');
37
37
  }
38
- /**
39
- * Validate OpenCode configuration against the official JSON Schema
40
- */
41
- function validateOpenCodeConfig(config) {
42
- var _a;
43
- try {
44
- if (!validateFunction) {
45
- return { valid: false, errors: ["Schema validator not initialized"] };
46
- }
47
- const isValid = validateFunction(config);
48
- if (isValid) {
49
- return { valid: true };
50
- }
51
- else {
52
- const errors = ((_a = validateFunction.errors) === null || _a === void 0 ? void 0 : _a.map((err) => {
53
- const path = err.instancePath || err.schemaPath || "root";
54
- const message = err.message || "Unknown error";
55
- return `${path}: ${message}`;
56
- })) || ["Unknown validation error"];
57
- return { valid: false, errors };
58
- }
59
- }
60
- catch (error) {
61
- console.error("Validation error:", error);
62
- return { valid: false, errors: ["Validation process failed"] };
63
- }
64
- }
65
- exports.validateOpenCodeConfig = validateOpenCodeConfig;
66
38
  /**
67
39
  * Fix common OpenCode configuration issues
68
40
  */
69
41
  function fixOpenCodeConfig(config) {
70
- const fixed = Object.assign({}, config);
42
+ const fixed = { ...config };
71
43
  // Fix tools.compact - should be boolean, not object
72
- if (fixed.tools && typeof fixed.tools.compact === "object") {
73
- console.warn("⚠️ Converting tools.compact from object to boolean");
44
+ if (fixed.tools && typeof fixed.tools.compact === 'object') {
45
+ console.warn('⚠️ Converting tools.compact from object to boolean');
74
46
  // If it has properties, assume it should be enabled
75
47
  fixed.tools.compact = true;
76
48
  }
77
49
  // Remove invalid properties
78
- const invalidProps = ["maxTokens", "contextWindow"];
79
- invalidProps.forEach(prop => {
80
- if (fixed[prop] !== undefined) {
81
- console.warn(`⚠️ Removing invalid property: ${prop}`);
82
- delete fixed[prop];
50
+ const invalidProperties = ['maxTokens', 'contextWindow'];
51
+ for (const property of invalidProperties) {
52
+ if (fixed[property] !== undefined) {
53
+ console.warn(`⚠️ Removing invalid property: ${property}`);
54
+ delete fixed[property];
83
55
  }
84
- });
56
+ }
85
57
  // Fix provider models with invalid properties
86
58
  if (fixed.provider) {
87
59
  Object.values(fixed.provider).forEach((provider) => {
88
- if (provider === null || provider === void 0 ? void 0 : provider.models) {
60
+ if (provider?.models) {
89
61
  Object.values(provider.models).forEach((model) => {
90
- if (model && typeof model === "object") {
91
- // Move maxTokens/contextWindow to proper structure if needed
92
- if (model.maxTokens || model.contextWindow) {
93
- if (!model.limit)
94
- model.limit = {};
95
- // Use the larger of maxTokens/contextWindow for context
96
- const contextValues = [model.maxTokens, model.contextWindow].filter(Boolean);
97
- if (contextValues.length > 0) {
98
- const newContext = Math.max(...contextValues);
99
- if (!model.limit.context || newContext > model.limit.context) {
100
- model.limit.context = newContext;
101
- }
102
- }
103
- // Set a reasonable default for output if not present
104
- // (typically 1/4 to 1/8 of context window)
105
- if (!model.limit.output && model.limit.context) {
106
- model.limit.output = Math.floor(model.limit.context / 4);
62
+ if (model &&
63
+ typeof model === 'object' && // Move maxTokens/contextWindow to proper structure if needed
64
+ (model.maxTokens || model.contextWindow)) {
65
+ if (!model.limit)
66
+ model.limit = {};
67
+ // Use the larger of maxTokens/contextWindow for context
68
+ const contextValues = [model.maxTokens, model.contextWindow].filter(Boolean);
69
+ if (contextValues.length > 0) {
70
+ const newContext = Math.max(...contextValues);
71
+ if (!model.limit.context || newContext > model.limit.context) {
72
+ model.limit.context = newContext;
107
73
  }
108
- delete model.maxTokens;
109
- delete model.contextWindow;
110
- console.warn("⚠️ Moved maxTokens/contextWindow to limit.context/output");
111
74
  }
75
+ // Set a reasonable default for output if not present
76
+ // (typically 1/4 to 1/8 of context window)
77
+ if (!model.limit.output && model.limit.context) {
78
+ model.limit.output = Math.floor(model.limit.context / 4);
79
+ }
80
+ delete model.maxTokens;
81
+ delete model.contextWindow;
82
+ console.warn('⚠️ Moved maxTokens/contextWindow to limit.context/output');
112
83
  }
113
84
  });
114
85
  }
@@ -117,3 +88,30 @@ function fixOpenCodeConfig(config) {
117
88
  return fixed;
118
89
  }
119
90
  exports.fixOpenCodeConfig = fixOpenCodeConfig;
91
+ /**
92
+ * Validate OpenCode configuration against the official JSON Schema
93
+ */
94
+ function validateOpenCodeConfig(config) {
95
+ try {
96
+ if (!validateFunction) {
97
+ return { errors: ['Schema validator not initialized'], valid: false };
98
+ }
99
+ const isValid = validateFunction(config);
100
+ if (isValid) {
101
+ return { valid: true };
102
+ }
103
+ else {
104
+ const errors = validateFunction.errors?.map((error) => {
105
+ const path = error.instancePath || error.schemaPath || 'root';
106
+ const message = error.message || 'Unknown error';
107
+ return `${path}: ${message}`;
108
+ }) || ['Unknown validation error'];
109
+ return { errors, valid: false };
110
+ }
111
+ }
112
+ catch (error) {
113
+ console.error('Validation error:', error);
114
+ return { errors: ['Validation process failed'], valid: false };
115
+ }
116
+ }
117
+ exports.validateOpenCodeConfig = validateOpenCodeConfig;
@@ -24,43 +24,24 @@ var __importStar = (this && this.__importStar) || function (mod) {
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.TokenManager = void 0;
27
- const fs = __importStar(require("fs"));
28
- const path = __importStar(require("path"));
29
- const os = __importStar(require("os"));
27
+ const fs = __importStar(require("node:fs"));
28
+ const os = __importStar(require("node:os"));
29
+ const path = __importStar(require("node:path"));
30
30
  const logger_1 = require("./logger");
31
- /**
32
- * Extract the expiration time from a JWT token
33
- * @param accessToken The JWT access token
34
- * @returns The expiration timestamp in milliseconds, or 0 if invalid
35
- */
36
- function extractJwtExpiresAt(accessToken) {
37
- try {
38
- const parts = accessToken.split(".");
39
- if (parts.length !== 3)
40
- return 0;
41
- const payload = Buffer.from(parts[1], "base64url").toString("utf8");
42
- const decoded = JSON.parse(payload);
43
- if (typeof decoded.exp === "number") {
44
- return decoded.exp * 1000; // JWT exp is in seconds, convert to milliseconds
45
- }
46
- }
47
- catch (_a) {
48
- // If decoding fails, return 0 (treated as expired)
49
- }
50
- return 0;
51
- }
52
31
  /**
53
32
  * Manages authentication tokens including refresh functionality
54
33
  */
55
34
  class TokenManager {
35
+ static instance;
36
+ tokenData = null;
37
+ tokenFilePath;
56
38
  constructor() {
57
- this.tokenData = null;
58
39
  // Set up token file path in user's home directory
59
- const bergetDir = path.join(os.homedir(), ".berget");
40
+ const bergetDir = path.join(os.homedir(), '.berget');
60
41
  if (!fs.existsSync(bergetDir)) {
61
42
  fs.mkdirSync(bergetDir, { recursive: true });
62
43
  }
63
- this.tokenFilePath = path.join(bergetDir, "auth.json");
44
+ this.tokenFilePath = path.join(bergetDir, 'auth.json');
64
45
  this.loadToken();
65
46
  }
66
47
  static getInstance() {
@@ -70,40 +51,11 @@ class TokenManager {
70
51
  return TokenManager.instance;
71
52
  }
72
53
  /**
73
- * Load token data from file
74
- */
75
- loadToken() {
76
- try {
77
- if (fs.existsSync(this.tokenFilePath)) {
78
- const data = fs.readFileSync(this.tokenFilePath, "utf8");
79
- this.tokenData = JSON.parse(data);
80
- }
81
- }
82
- catch (_a) {
83
- logger_1.logger.error("Failed to load authentication token");
84
- this.tokenData = null;
85
- }
86
- }
87
- /**
88
- * Save token data to file
54
+ * Clear all token data
89
55
  */
90
- saveToken() {
91
- try {
92
- if (this.tokenData) {
93
- fs.writeFileSync(this.tokenFilePath, JSON.stringify(this.tokenData, null, 2));
94
- // Set file permissions to be readable only by the owner
95
- fs.chmodSync(this.tokenFilePath, 0o600);
96
- }
97
- else {
98
- // If token data is null, remove the file
99
- if (fs.existsSync(this.tokenFilePath)) {
100
- fs.unlinkSync(this.tokenFilePath);
101
- }
102
- }
103
- }
104
- catch (_a) {
105
- logger_1.logger.error("Failed to save authentication token");
106
- }
56
+ clearTokens() {
57
+ this.tokenData = null;
58
+ this.saveToken();
107
59
  }
108
60
  /**
109
61
  * Get the current access token
@@ -163,8 +115,8 @@ class TokenManager {
163
115
  const expiresAt = jwtExpiresAt > 0 ? jwtExpiresAt : Date.now() + expiresIn * 1000;
164
116
  this.tokenData = {
165
117
  access_token: accessToken,
166
- refresh_token: refreshToken,
167
118
  expires_at: expiresAt,
119
+ refresh_token: refreshToken,
168
120
  };
169
121
  this.saveToken();
170
122
  }
@@ -184,11 +136,61 @@ class TokenManager {
184
136
  this.saveToken();
185
137
  }
186
138
  /**
187
- * Clear all token data
139
+ * Load token data from file
188
140
  */
189
- clearTokens() {
190
- this.tokenData = null;
191
- this.saveToken();
141
+ loadToken() {
142
+ try {
143
+ if (fs.existsSync(this.tokenFilePath)) {
144
+ const data = fs.readFileSync(this.tokenFilePath, 'utf8');
145
+ this.tokenData = JSON.parse(data);
146
+ }
147
+ }
148
+ catch {
149
+ logger_1.logger.error('Failed to load authentication token');
150
+ this.tokenData = null;
151
+ }
152
+ }
153
+ /**
154
+ * Save token data to file
155
+ */
156
+ saveToken() {
157
+ try {
158
+ if (this.tokenData) {
159
+ fs.writeFileSync(this.tokenFilePath, JSON.stringify(this.tokenData, null, 2));
160
+ // Set file permissions to be readable only by the owner
161
+ fs.chmodSync(this.tokenFilePath, 0o600);
162
+ }
163
+ else {
164
+ // If token data is null, remove the file
165
+ if (fs.existsSync(this.tokenFilePath)) {
166
+ fs.unlinkSync(this.tokenFilePath);
167
+ }
168
+ }
169
+ }
170
+ catch {
171
+ logger_1.logger.error('Failed to save authentication token');
172
+ }
192
173
  }
193
174
  }
194
175
  exports.TokenManager = TokenManager;
176
+ /**
177
+ * Extract the expiration time from a JWT token
178
+ * @param accessToken The JWT access token
179
+ * @returns The expiration timestamp in milliseconds, or 0 if invalid
180
+ */
181
+ function extractJwtExpiresAt(accessToken) {
182
+ try {
183
+ const parts = accessToken.split('.');
184
+ if (parts.length !== 3)
185
+ return 0;
186
+ const payload = Buffer.from(parts[1], 'base64url').toString('utf8');
187
+ const decoded = JSON.parse(payload);
188
+ if (typeof decoded.exp === 'number') {
189
+ return decoded.exp * 1000; // JWT exp is in seconds, convert to milliseconds
190
+ }
191
+ }
192
+ catch {
193
+ // If decoding fails, return 0 (treated as expired)
194
+ }
195
+ return 0;
196
+ }
@@ -1,29 +1,20 @@
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
- const vitest_1 = require("vitest");
13
3
  const commander_1 = require("commander");
4
+ const vitest_1 = require("vitest");
14
5
  const chat_1 = require("../../src/commands/chat");
15
6
  const chat_service_1 = require("../../src/services/chat-service");
16
7
  const default_api_key_1 = require("../../src/utils/default-api-key");
17
8
  // Mock dependencies
18
- vitest_1.vi.mock("../../src/services/chat-service");
19
- vitest_1.vi.mock("../../src/utils/default-api-key");
20
- vitest_1.vi.mock("readline", () => ({
9
+ vitest_1.vi.mock('../../src/services/chat-service');
10
+ vitest_1.vi.mock('../../src/utils/default-api-key');
11
+ vitest_1.vi.mock('readline', () => ({
21
12
  createInterface: vitest_1.vi.fn(() => ({
22
- question: vitest_1.vi.fn(),
23
13
  close: vitest_1.vi.fn(),
14
+ question: vitest_1.vi.fn(),
24
15
  })),
25
16
  }));
26
- (0, vitest_1.describe)("Chat Commands", () => {
17
+ (0, vitest_1.describe)('Chat Commands', () => {
27
18
  let program;
28
19
  let mockChatService;
29
20
  let mockDefaultApiKeyManager;
@@ -46,32 +37,32 @@ vitest_1.vi.mock("readline", () => ({
46
37
  (0, vitest_1.afterEach)(() => {
47
38
  vitest_1.vi.clearAllMocks();
48
39
  });
49
- (0, vitest_1.describe)("chat run command", () => {
50
- (0, vitest_1.it)("should use berget/glm-4.7 as default model", () => {
51
- const chatCommand = program.commands.find(cmd => cmd.name() === "chat");
52
- const runCommand = chatCommand === null || chatCommand === void 0 ? void 0 : chatCommand.commands.find(cmd => cmd.name() === "run");
40
+ (0, vitest_1.describe)('chat run command', () => {
41
+ (0, vitest_1.it)('should use berget/glm-4.7 as default model', () => {
42
+ const chatCommand = program.commands.find((cmd) => cmd.name() === 'chat');
43
+ const runCommand = chatCommand?.commands.find((cmd) => cmd.name() === 'run');
53
44
  (0, vitest_1.expect)(runCommand).toBeDefined();
54
45
  // Check the help text which contains the default model
55
- const helpText = runCommand === null || runCommand === void 0 ? void 0 : runCommand.helpInformation();
56
- (0, vitest_1.expect)(helpText).toContain("glm-4.7");
46
+ const helpText = runCommand?.helpInformation();
47
+ (0, vitest_1.expect)(helpText).toContain('glm-4.7');
57
48
  });
58
- (0, vitest_1.it)("should have streaming enabled by default", () => {
59
- const chatCommand = program.commands.find(cmd => cmd.name() === "chat");
60
- const runCommand = chatCommand === null || chatCommand === void 0 ? void 0 : chatCommand.commands.find(cmd => cmd.name() === "run");
49
+ (0, vitest_1.it)('should have streaming enabled by default', () => {
50
+ const chatCommand = program.commands.find((cmd) => cmd.name() === 'chat');
51
+ const runCommand = chatCommand?.commands.find((cmd) => cmd.name() === 'run');
61
52
  (0, vitest_1.expect)(runCommand).toBeDefined();
62
53
  // Check that the option is --no-stream (meaning streaming is default)
63
- const streamOption = runCommand === null || runCommand === void 0 ? void 0 : runCommand.options.find(opt => opt.long === "--no-stream");
54
+ const streamOption = runCommand?.options.find((opt) => opt.long === '--no-stream');
64
55
  (0, vitest_1.expect)(streamOption).toBeDefined();
65
- (0, vitest_1.expect)(streamOption === null || streamOption === void 0 ? void 0 : streamOption.description).toContain("Disable streaming");
56
+ (0, vitest_1.expect)(streamOption?.description).toContain('Disable streaming');
66
57
  });
67
- (0, vitest_1.it)("should create completion with correct default options", () => __awaiter(void 0, void 0, void 0, function* () {
58
+ (0, vitest_1.it)('should create completion with correct default options', async () => {
68
59
  // Mock API key
69
- process.env.BERGET_API_KEY = "test-key";
60
+ process.env.BERGET_API_KEY = 'test-key';
70
61
  // Mock successful completion
71
62
  mockChatService.createCompletion.mockResolvedValue({
72
63
  choices: [
73
64
  {
74
- message: { content: "Test response" },
65
+ message: { content: 'Test response' },
75
66
  },
76
67
  ],
77
68
  });
@@ -81,29 +72,29 @@ vitest_1.vi.mock("readline", () => ({
81
72
  (0, vitest_1.expect)(mockChatService.createCompletion).not.toHaveBeenCalled();
82
73
  // Clean up
83
74
  delete process.env.BERGET_API_KEY;
84
- }));
75
+ });
85
76
  });
86
- (0, vitest_1.describe)("chat list command", () => {
87
- (0, vitest_1.it)("should list available models", () => __awaiter(void 0, void 0, void 0, function* () {
77
+ (0, vitest_1.describe)('chat list command', () => {
78
+ (0, vitest_1.it)('should list available models', async () => {
88
79
  const mockModels = {
89
80
  data: [
90
81
  {
91
- id: "gpt-oss",
92
- owned_by: "openai",
93
82
  active: true,
94
83
  capabilities: {
95
- vision: false,
96
84
  function_calling: true,
97
85
  json_mode: true,
86
+ vision: false,
98
87
  },
88
+ id: 'gpt-oss',
89
+ owned_by: 'openai',
99
90
  },
100
91
  ],
101
92
  };
102
93
  mockChatService.listModels.mockResolvedValue(mockModels);
103
- const chatCommand = program.commands.find(cmd => cmd.name() === "chat");
104
- const listCommand = chatCommand === null || chatCommand === void 0 ? void 0 : chatCommand.commands.find(cmd => cmd.name() === "list");
94
+ const chatCommand = program.commands.find((cmd) => cmd.name() === 'chat');
95
+ const listCommand = chatCommand?.commands.find((cmd) => cmd.name() === 'list');
105
96
  (0, vitest_1.expect)(listCommand).toBeDefined();
106
- (0, vitest_1.expect)(listCommand === null || listCommand === void 0 ? void 0 : listCommand.description()).toBe("List available chat models");
107
- }));
97
+ (0, vitest_1.expect)(listCommand?.description()).toBe('List available chat models');
98
+ });
108
99
  });
109
100
  });