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.
- package/.github/workflows/publish.yml +8 -8
- package/.github/workflows/test.yml +12 -6
- package/.husky/pre-commit +1 -0
- package/.prettierignore +15 -0
- package/.prettierrc +5 -3
- package/CONTRIBUTING.md +38 -0
- package/README.md +2 -148
- package/dist/index.js +21 -21
- package/dist/package.json +30 -2
- package/dist/src/agents/app.js +28 -0
- package/dist/src/agents/backend.js +25 -0
- package/dist/src/agents/devops.js +34 -0
- package/dist/src/agents/frontend.js +25 -0
- package/dist/src/agents/fullstack.js +25 -0
- package/dist/src/agents/index.js +61 -0
- package/dist/src/agents/quality.js +70 -0
- package/dist/src/agents/security.js +26 -0
- package/dist/src/agents/types.js +2 -0
- package/dist/src/client.js +54 -62
- package/dist/src/commands/api-keys.js +132 -140
- package/dist/src/commands/auth.js +9 -9
- package/dist/src/commands/autocomplete.js +9 -9
- package/dist/src/commands/billing.js +7 -9
- package/dist/src/commands/chat.js +90 -92
- package/dist/src/commands/clusters.js +12 -12
- package/dist/src/commands/code/__tests__/auth-sync.test.js +348 -0
- package/dist/src/commands/code/__tests__/fake-api-key-service.js +23 -0
- package/dist/src/commands/code/__tests__/fake-auth-service.js +55 -0
- package/dist/src/commands/code/__tests__/fake-command-runner.js +50 -0
- package/dist/src/commands/code/__tests__/fake-file-store.js +55 -0
- package/dist/src/commands/code/__tests__/fake-prompter.js +133 -0
- package/dist/src/commands/code/__tests__/setup-flow.test.js +505 -0
- package/dist/src/commands/code/adapters/clack-prompter.js +81 -0
- package/dist/src/commands/code/adapters/fs-file-store.js +80 -0
- package/dist/src/commands/code/adapters/spawn-command-runner.js +53 -0
- package/dist/src/commands/code/auth-sync.js +283 -0
- package/dist/src/commands/code/errors.js +27 -0
- package/dist/src/commands/code/ports/auth-services.js +2 -0
- package/dist/src/commands/code/ports/command-runner.js +2 -0
- package/dist/src/commands/code/ports/file-store.js +2 -0
- package/dist/src/commands/code/ports/prompter.js +2 -0
- package/dist/src/commands/code/setup.js +533 -0
- package/dist/src/commands/code.js +223 -779
- package/dist/src/commands/models.js +13 -15
- package/dist/src/commands/users.js +6 -8
- package/dist/src/constants/command-structure.js +116 -114
- package/dist/src/services/api-key-service.js +43 -48
- package/dist/src/services/auth-service.js +60 -299
- package/dist/src/services/browser-auth.js +278 -0
- package/dist/src/services/chat-service.js +78 -91
- package/dist/src/services/cluster-service.js +6 -6
- package/dist/src/services/collaborator-service.js +5 -8
- package/dist/src/services/flux-service.js +5 -8
- package/dist/src/services/helm-service.js +5 -8
- package/dist/src/services/kubectl-service.js +7 -10
- package/dist/src/utils/config-checker.js +5 -5
- package/dist/src/utils/config-loader.js +25 -25
- package/dist/src/utils/default-api-key.js +23 -23
- package/dist/src/utils/env-manager.js +7 -7
- package/dist/src/utils/error-handler.js +60 -61
- package/dist/src/utils/logger.js +7 -7
- package/dist/src/utils/markdown-renderer.js +2 -2
- package/dist/src/utils/opencode-validator.js +17 -20
- package/dist/src/utils/token-manager.js +38 -11
- package/dist/tests/commands/chat.test.js +24 -24
- package/dist/tests/commands/code.test.js +169 -138
- package/dist/tests/utils/config-loader.test.js +114 -114
- package/dist/tests/utils/env-manager.test.js +57 -57
- package/dist/tests/utils/opencode-validator.test.js +44 -43
- package/dist/vitest.config.js +1 -1
- package/eslint.config.mjs +47 -0
- package/index.ts +42 -48
- package/package.json +30 -2
- package/src/agents/app.ts +27 -0
- package/src/agents/backend.ts +24 -0
- package/src/agents/devops.ts +33 -0
- package/src/agents/frontend.ts +24 -0
- package/src/agents/fullstack.ts +24 -0
- package/src/agents/index.ts +71 -0
- package/src/agents/quality.ts +69 -0
- package/src/agents/security.ts +26 -0
- package/src/agents/types.ts +17 -0
- package/src/client.ts +125 -167
- package/src/commands/api-keys.ts +261 -358
- package/src/commands/auth.ts +24 -30
- package/src/commands/autocomplete.ts +12 -12
- package/src/commands/billing.ts +22 -27
- package/src/commands/chat.ts +230 -323
- package/src/commands/clusters.ts +33 -33
- package/src/commands/code/__tests__/auth-sync.test.ts +481 -0
- package/src/commands/code/__tests__/fake-api-key-service.ts +13 -0
- package/src/commands/code/__tests__/fake-auth-service.ts +50 -0
- package/src/commands/code/__tests__/fake-command-runner.ts +44 -0
- package/src/commands/code/__tests__/fake-file-store.ts +44 -0
- package/src/commands/code/__tests__/fake-prompter.ts +121 -0
- package/src/commands/code/__tests__/setup-flow.test.ts +628 -0
- package/src/commands/code/adapters/clack-prompter.ts +55 -0
- package/src/commands/code/adapters/fs-file-store.ts +37 -0
- package/src/commands/code/adapters/spawn-command-runner.ts +40 -0
- package/src/commands/code/auth-sync.ts +329 -0
- package/src/commands/code/errors.ts +23 -0
- package/src/commands/code/ports/auth-services.ts +14 -0
- package/src/commands/code/ports/command-runner.ts +10 -0
- package/src/commands/code/ports/file-store.ts +7 -0
- package/src/commands/code/ports/prompter.ts +29 -0
- package/src/commands/code/setup.ts +630 -0
- package/src/commands/code.ts +335 -1074
- package/src/commands/index.ts +19 -19
- package/src/commands/models.ts +32 -37
- package/src/commands/users.ts +15 -22
- package/src/constants/command-structure.ts +120 -140
- package/src/services/api-key-service.ts +96 -113
- package/src/services/auth-service.ts +92 -339
- package/src/services/browser-auth.ts +296 -0
- package/src/services/chat-service.ts +246 -279
- package/src/services/cluster-service.ts +29 -32
- package/src/services/collaborator-service.ts +13 -18
- package/src/services/flux-service.ts +16 -18
- package/src/services/helm-service.ts +16 -18
- package/src/services/kubectl-service.ts +12 -14
- package/src/types/api.d.ts +924 -926
- package/src/types/json.d.ts +3 -3
- package/src/utils/config-checker.ts +10 -10
- package/src/utils/config-loader.ts +110 -127
- package/src/utils/default-api-key.ts +81 -93
- package/src/utils/env-manager.ts +36 -40
- package/src/utils/error-handler.ts +83 -78
- package/src/utils/logger.ts +41 -41
- package/src/utils/markdown-renderer.ts +11 -11
- package/src/utils/opencode-validator.ts +51 -56
- package/src/utils/token-manager.ts +84 -64
- package/templates/agents/app.md +23 -0
- package/templates/agents/backend.md +23 -0
- package/templates/agents/devops.md +30 -0
- package/templates/agents/frontend.md +25 -0
- package/templates/agents/fullstack.md +23 -0
- package/templates/agents/quality.md +69 -0
- package/templates/agents/security.md +21 -0
- package/tests/commands/chat.test.ts +60 -70
- package/tests/commands/code.test.ts +346 -345
- package/tests/utils/config-loader.test.ts +260 -260
- package/tests/utils/env-manager.test.ts +127 -134
- package/tests/utils/opencode-validator.test.ts +65 -69
- package/tsconfig.json +2 -2
- package/vitest.config.ts +3 -3
- package/AGENTS.md +0 -374
- package/TODO.md +0 -19
- package/opencode.json +0 -146
|
@@ -11,12 +11,12 @@ const path_1 = require("path");
|
|
|
11
11
|
const path_2 = require("path");
|
|
12
12
|
// Load the official OpenCode JSON Schema
|
|
13
13
|
const __dirname = (0, path_2.dirname)(__filename);
|
|
14
|
-
const schemaPath = (0, path_1.join)(__dirname,
|
|
14
|
+
const schemaPath = (0, 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,
|
|
19
|
+
const schemaContent = (0, 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({
|
|
@@ -32,8 +32,8 @@ try {
|
|
|
32
32
|
validateFunction = ajv.compile(openCodeSchema);
|
|
33
33
|
}
|
|
34
34
|
catch (error) {
|
|
35
|
-
console.error(
|
|
36
|
-
throw new Error(
|
|
35
|
+
console.error("Failed to load OpenCode schema:", error);
|
|
36
|
+
throw new Error("Could not initialize OpenCode validator");
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* Validate OpenCode configuration against the official JSON Schema
|
|
@@ -42,7 +42,7 @@ function validateOpenCodeConfig(config) {
|
|
|
42
42
|
var _a;
|
|
43
43
|
try {
|
|
44
44
|
if (!validateFunction) {
|
|
45
|
-
return { valid: false, errors: [
|
|
45
|
+
return { valid: false, errors: ["Schema validator not initialized"] };
|
|
46
46
|
}
|
|
47
47
|
const isValid = validateFunction(config);
|
|
48
48
|
if (isValid) {
|
|
@@ -50,16 +50,16 @@ function validateOpenCodeConfig(config) {
|
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
52
|
const errors = ((_a = validateFunction.errors) === null || _a === void 0 ? void 0 : _a.map((err) => {
|
|
53
|
-
const path = err.instancePath || err.schemaPath ||
|
|
54
|
-
const message = err.message ||
|
|
53
|
+
const path = err.instancePath || err.schemaPath || "root";
|
|
54
|
+
const message = err.message || "Unknown error";
|
|
55
55
|
return `${path}: ${message}`;
|
|
56
|
-
})) || [
|
|
56
|
+
})) || ["Unknown validation error"];
|
|
57
57
|
return { valid: false, errors };
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
catch (error) {
|
|
61
|
-
console.error(
|
|
62
|
-
return { valid: false, errors: [
|
|
61
|
+
console.error("Validation error:", error);
|
|
62
|
+
return { valid: false, errors: ["Validation process failed"] };
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
exports.validateOpenCodeConfig = validateOpenCodeConfig;
|
|
@@ -69,14 +69,14 @@ exports.validateOpenCodeConfig = validateOpenCodeConfig;
|
|
|
69
69
|
function fixOpenCodeConfig(config) {
|
|
70
70
|
const fixed = Object.assign({}, config);
|
|
71
71
|
// Fix tools.compact - should be boolean, not object
|
|
72
|
-
if (fixed.tools && typeof fixed.tools.compact ===
|
|
73
|
-
console.warn(
|
|
72
|
+
if (fixed.tools && typeof fixed.tools.compact === "object") {
|
|
73
|
+
console.warn("⚠️ Converting tools.compact from object to boolean");
|
|
74
74
|
// If it has properties, assume it should be enabled
|
|
75
75
|
fixed.tools.compact = true;
|
|
76
76
|
}
|
|
77
77
|
// Remove invalid properties
|
|
78
|
-
const invalidProps = [
|
|
79
|
-
invalidProps.forEach(
|
|
78
|
+
const invalidProps = ["maxTokens", "contextWindow"];
|
|
79
|
+
invalidProps.forEach(prop => {
|
|
80
80
|
if (fixed[prop] !== undefined) {
|
|
81
81
|
console.warn(`⚠️ Removing invalid property: ${prop}`);
|
|
82
82
|
delete fixed[prop];
|
|
@@ -87,16 +87,13 @@ function fixOpenCodeConfig(config) {
|
|
|
87
87
|
Object.values(fixed.provider).forEach((provider) => {
|
|
88
88
|
if (provider === null || provider === void 0 ? void 0 : provider.models) {
|
|
89
89
|
Object.values(provider.models).forEach((model) => {
|
|
90
|
-
if (model && typeof model ===
|
|
90
|
+
if (model && typeof model === "object") {
|
|
91
91
|
// Move maxTokens/contextWindow to proper structure if needed
|
|
92
92
|
if (model.maxTokens || model.contextWindow) {
|
|
93
93
|
if (!model.limit)
|
|
94
94
|
model.limit = {};
|
|
95
95
|
// Use the larger of maxTokens/contextWindow for context
|
|
96
|
-
const contextValues = [
|
|
97
|
-
model.maxTokens,
|
|
98
|
-
model.contextWindow,
|
|
99
|
-
].filter(Boolean);
|
|
96
|
+
const contextValues = [model.maxTokens, model.contextWindow].filter(Boolean);
|
|
100
97
|
if (contextValues.length > 0) {
|
|
101
98
|
const newContext = Math.max(...contextValues);
|
|
102
99
|
if (!model.limit.context || newContext > model.limit.context) {
|
|
@@ -110,7 +107,7 @@ function fixOpenCodeConfig(config) {
|
|
|
110
107
|
}
|
|
111
108
|
delete model.maxTokens;
|
|
112
109
|
delete model.contextWindow;
|
|
113
|
-
console.warn(
|
|
110
|
+
console.warn("⚠️ Moved maxTokens/contextWindow to limit.context/output");
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
});
|
|
@@ -28,6 +28,27 @@ const fs = __importStar(require("fs"));
|
|
|
28
28
|
const path = __importStar(require("path"));
|
|
29
29
|
const os = __importStar(require("os"));
|
|
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
|
+
}
|
|
31
52
|
/**
|
|
32
53
|
* Manages authentication tokens including refresh functionality
|
|
33
54
|
*/
|
|
@@ -35,11 +56,11 @@ class TokenManager {
|
|
|
35
56
|
constructor() {
|
|
36
57
|
this.tokenData = null;
|
|
37
58
|
// Set up token file path in user's home directory
|
|
38
|
-
const bergetDir = path.join(os.homedir(),
|
|
59
|
+
const bergetDir = path.join(os.homedir(), ".berget");
|
|
39
60
|
if (!fs.existsSync(bergetDir)) {
|
|
40
61
|
fs.mkdirSync(bergetDir, { recursive: true });
|
|
41
62
|
}
|
|
42
|
-
this.tokenFilePath = path.join(bergetDir,
|
|
63
|
+
this.tokenFilePath = path.join(bergetDir, "auth.json");
|
|
43
64
|
this.loadToken();
|
|
44
65
|
}
|
|
45
66
|
static getInstance() {
|
|
@@ -54,12 +75,12 @@ class TokenManager {
|
|
|
54
75
|
loadToken() {
|
|
55
76
|
try {
|
|
56
77
|
if (fs.existsSync(this.tokenFilePath)) {
|
|
57
|
-
const data = fs.readFileSync(this.tokenFilePath,
|
|
78
|
+
const data = fs.readFileSync(this.tokenFilePath, "utf8");
|
|
58
79
|
this.tokenData = JSON.parse(data);
|
|
59
80
|
}
|
|
60
81
|
}
|
|
61
|
-
catch (
|
|
62
|
-
logger_1.logger.error(
|
|
82
|
+
catch (_a) {
|
|
83
|
+
logger_1.logger.error("Failed to load authentication token");
|
|
63
84
|
this.tokenData = null;
|
|
64
85
|
}
|
|
65
86
|
}
|
|
@@ -80,8 +101,8 @@ class TokenManager {
|
|
|
80
101
|
}
|
|
81
102
|
}
|
|
82
103
|
}
|
|
83
|
-
catch (
|
|
84
|
-
logger_1.logger.error(
|
|
104
|
+
catch (_a) {
|
|
105
|
+
logger_1.logger.error("Failed to save authentication token");
|
|
85
106
|
}
|
|
86
107
|
}
|
|
87
108
|
/**
|
|
@@ -134,26 +155,32 @@ class TokenManager {
|
|
|
134
155
|
* Set new token data
|
|
135
156
|
* @param accessToken The new access token
|
|
136
157
|
* @param refreshToken The new refresh token
|
|
137
|
-
* @param expiresIn Expiration time in seconds
|
|
158
|
+
* @param expiresIn Expiration time in seconds (fallback if JWT parsing fails)
|
|
138
159
|
*/
|
|
139
160
|
setTokens(accessToken, refreshToken, expiresIn) {
|
|
161
|
+
// Extract the actual expiry time from the JWT token
|
|
162
|
+
const jwtExpiresAt = extractJwtExpiresAt(accessToken);
|
|
163
|
+
const expiresAt = jwtExpiresAt > 0 ? jwtExpiresAt : Date.now() + expiresIn * 1000;
|
|
140
164
|
this.tokenData = {
|
|
141
165
|
access_token: accessToken,
|
|
142
166
|
refresh_token: refreshToken,
|
|
143
|
-
expires_at:
|
|
167
|
+
expires_at: expiresAt,
|
|
144
168
|
};
|
|
145
169
|
this.saveToken();
|
|
146
170
|
}
|
|
147
171
|
/**
|
|
148
172
|
* Update just the access token and its expiration
|
|
149
173
|
* @param accessToken The new access token
|
|
150
|
-
* @param expiresIn Expiration time in seconds
|
|
174
|
+
* @param expiresIn Expiration time in seconds (fallback if JWT parsing fails)
|
|
151
175
|
*/
|
|
152
176
|
updateAccessToken(accessToken, expiresIn) {
|
|
153
177
|
if (!this.tokenData)
|
|
154
178
|
return;
|
|
179
|
+
// Extract the actual expiry time from the JWT token
|
|
180
|
+
const jwtExpiresAt = extractJwtExpiresAt(accessToken);
|
|
181
|
+
const expiresAt = jwtExpiresAt > 0 ? jwtExpiresAt : Date.now() + expiresIn * 1000;
|
|
155
182
|
this.tokenData.access_token = accessToken;
|
|
156
|
-
this.tokenData.expires_at =
|
|
183
|
+
this.tokenData.expires_at = expiresAt;
|
|
157
184
|
this.saveToken();
|
|
158
185
|
}
|
|
159
186
|
/**
|
|
@@ -15,15 +15,15 @@ const chat_1 = require("../../src/commands/chat");
|
|
|
15
15
|
const chat_service_1 = require("../../src/services/chat-service");
|
|
16
16
|
const default_api_key_1 = require("../../src/utils/default-api-key");
|
|
17
17
|
// Mock dependencies
|
|
18
|
-
vitest_1.vi.mock(
|
|
19
|
-
vitest_1.vi.mock(
|
|
20
|
-
vitest_1.vi.mock(
|
|
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", () => ({
|
|
21
21
|
createInterface: vitest_1.vi.fn(() => ({
|
|
22
22
|
question: vitest_1.vi.fn(),
|
|
23
23
|
close: vitest_1.vi.fn(),
|
|
24
24
|
})),
|
|
25
25
|
}));
|
|
26
|
-
(0, vitest_1.describe)(
|
|
26
|
+
(0, vitest_1.describe)("Chat Commands", () => {
|
|
27
27
|
let program;
|
|
28
28
|
let mockChatService;
|
|
29
29
|
let mockDefaultApiKeyManager;
|
|
@@ -46,32 +46,32 @@ vitest_1.vi.mock('readline', () => ({
|
|
|
46
46
|
(0, vitest_1.afterEach)(() => {
|
|
47
47
|
vitest_1.vi.clearAllMocks();
|
|
48
48
|
});
|
|
49
|
-
(0, vitest_1.describe)(
|
|
50
|
-
(0, vitest_1.it)(
|
|
51
|
-
const chatCommand = program.commands.find(
|
|
52
|
-
const runCommand = chatCommand === null || chatCommand === void 0 ? void 0 : chatCommand.commands.find(
|
|
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");
|
|
53
53
|
(0, vitest_1.expect)(runCommand).toBeDefined();
|
|
54
54
|
// Check the help text which contains the default model
|
|
55
55
|
const helpText = runCommand === null || runCommand === void 0 ? void 0 : runCommand.helpInformation();
|
|
56
|
-
(0, vitest_1.expect)(helpText).toContain(
|
|
56
|
+
(0, vitest_1.expect)(helpText).toContain("glm-4.7");
|
|
57
57
|
});
|
|
58
|
-
(0, vitest_1.it)(
|
|
59
|
-
const chatCommand = program.commands.find(
|
|
60
|
-
const runCommand = chatCommand === null || chatCommand === void 0 ? void 0 : chatCommand.commands.find(
|
|
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");
|
|
61
61
|
(0, vitest_1.expect)(runCommand).toBeDefined();
|
|
62
62
|
// Check that the option is --no-stream (meaning streaming is default)
|
|
63
|
-
const streamOption = runCommand === null || runCommand === void 0 ? void 0 : runCommand.options.find(
|
|
63
|
+
const streamOption = runCommand === null || runCommand === void 0 ? void 0 : runCommand.options.find(opt => opt.long === "--no-stream");
|
|
64
64
|
(0, vitest_1.expect)(streamOption).toBeDefined();
|
|
65
|
-
(0, vitest_1.expect)(streamOption === null || streamOption === void 0 ? void 0 : streamOption.description).toContain(
|
|
65
|
+
(0, vitest_1.expect)(streamOption === null || streamOption === void 0 ? void 0 : streamOption.description).toContain("Disable streaming");
|
|
66
66
|
});
|
|
67
|
-
(0, vitest_1.it)(
|
|
67
|
+
(0, vitest_1.it)("should create completion with correct default options", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
68
|
// Mock API key
|
|
69
|
-
process.env.BERGET_API_KEY =
|
|
69
|
+
process.env.BERGET_API_KEY = "test-key";
|
|
70
70
|
// Mock successful completion
|
|
71
71
|
mockChatService.createCompletion.mockResolvedValue({
|
|
72
72
|
choices: [
|
|
73
73
|
{
|
|
74
|
-
message: { content:
|
|
74
|
+
message: { content: "Test response" },
|
|
75
75
|
},
|
|
76
76
|
],
|
|
77
77
|
});
|
|
@@ -83,13 +83,13 @@ vitest_1.vi.mock('readline', () => ({
|
|
|
83
83
|
delete process.env.BERGET_API_KEY;
|
|
84
84
|
}));
|
|
85
85
|
});
|
|
86
|
-
(0, vitest_1.describe)(
|
|
87
|
-
(0, vitest_1.it)(
|
|
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* () {
|
|
88
88
|
const mockModels = {
|
|
89
89
|
data: [
|
|
90
90
|
{
|
|
91
|
-
id:
|
|
92
|
-
owned_by:
|
|
91
|
+
id: "gpt-oss",
|
|
92
|
+
owned_by: "openai",
|
|
93
93
|
active: true,
|
|
94
94
|
capabilities: {
|
|
95
95
|
vision: false,
|
|
@@ -100,10 +100,10 @@ vitest_1.vi.mock('readline', () => ({
|
|
|
100
100
|
],
|
|
101
101
|
};
|
|
102
102
|
mockChatService.listModels.mockResolvedValue(mockModels);
|
|
103
|
-
const chatCommand = program.commands.find(
|
|
104
|
-
const listCommand = chatCommand === null || chatCommand === void 0 ? void 0 : chatCommand.commands.find(
|
|
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");
|
|
105
105
|
(0, vitest_1.expect)(listCommand).toBeDefined();
|
|
106
|
-
(0, vitest_1.expect)(listCommand === null || listCommand === void 0 ? void 0 : listCommand.description()).toBe(
|
|
106
|
+
(0, vitest_1.expect)(listCommand === null || listCommand === void 0 ? void 0 : listCommand.description()).toBe("List available chat models");
|
|
107
107
|
}));
|
|
108
108
|
});
|
|
109
109
|
});
|