berget 2.2.6 → 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 +2 -2
- package/.github/workflows/test.yml +10 -4
- package/.husky/pre-commit +1 -0
- package/.prettierignore +15 -0
- package/.prettierrc +7 -3
- package/CONTRIBUTING.md +38 -0
- package/README.md +2 -148
- package/dist/index.js +10 -11
- 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 +97 -117
- package/dist/src/commands/api-keys.js +75 -90
- package/dist/src/commands/auth.js +7 -16
- package/dist/src/commands/autocomplete.js +1 -1
- package/dist/src/commands/billing.js +6 -17
- package/dist/src/commands/chat.js +68 -101
- package/dist/src/commands/clusters.js +9 -18
- package/dist/src/commands/code/__tests__/auth-sync.test.js +351 -0
- package/dist/src/commands/code/__tests__/fake-api-key-service.js +13 -0
- package/dist/src/commands/code/__tests__/fake-auth-service.js +47 -0
- package/dist/src/commands/code/__tests__/fake-command-runner.js +21 -34
- package/dist/src/commands/code/__tests__/fake-file-store.js +20 -33
- package/dist/src/commands/code/__tests__/fake-prompter.js +83 -57
- package/dist/src/commands/code/__tests__/setup-flow.test.js +359 -92
- package/dist/src/commands/code/adapters/clack-prompter.js +15 -22
- package/dist/src/commands/code/adapters/fs-file-store.js +26 -40
- package/dist/src/commands/code/adapters/spawn-command-runner.js +27 -37
- package/dist/src/commands/code/auth-sync.js +270 -0
- package/dist/src/commands/code/errors.js +12 -9
- package/dist/src/commands/code/ports/auth-services.js +2 -0
- package/dist/src/commands/code/setup.js +387 -281
- package/dist/src/commands/code.js +205 -332
- package/dist/src/commands/index.js +5 -5
- package/dist/src/commands/models.js +6 -17
- package/dist/src/commands/users.js +5 -16
- package/dist/src/constants/command-structure.js +104 -104
- package/dist/src/services/api-key-service.js +132 -157
- package/dist/src/services/auth-service.js +89 -342
- package/dist/src/services/browser-auth.js +268 -0
- package/dist/src/services/chat-service.js +371 -401
- package/dist/src/services/cluster-service.js +47 -62
- package/dist/src/services/collaborator-service.js +10 -25
- package/dist/src/services/flux-service.js +14 -29
- package/dist/src/services/helm-service.js +10 -25
- package/dist/src/services/kubectl-service.js +16 -33
- package/dist/src/utils/config-checker.js +3 -3
- package/dist/src/utils/config-loader.js +95 -95
- package/dist/src/utils/default-api-key.js +124 -134
- package/dist/src/utils/env-manager.js +55 -66
- package/dist/src/utils/error-handler.js +20 -21
- package/dist/src/utils/logger.js +72 -65
- package/dist/src/utils/markdown-renderer.js +27 -27
- package/dist/src/utils/opencode-validator.js +63 -68
- package/dist/src/utils/token-manager.js +74 -45
- package/dist/tests/commands/chat.test.js +16 -25
- package/dist/tests/commands/code.test.js +95 -104
- package/dist/tests/utils/config-loader.test.js +48 -48
- package/dist/tests/utils/env-manager.test.js +43 -52
- package/dist/tests/utils/opencode-validator.test.js +22 -21
- package/dist/vitest.config.js +1 -1
- package/eslint.config.mjs +67 -0
- package/index.ts +35 -42
- 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 +73 -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 +118 -152
- package/src/commands/api-keys.ts +241 -333
- package/src/commands/auth.ts +22 -27
- package/src/commands/autocomplete.ts +9 -9
- package/src/commands/billing.ts +20 -24
- package/src/commands/chat.ts +248 -338
- package/src/commands/clusters.ts +27 -26
- package/src/commands/code/__tests__/auth-sync.test.ts +482 -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 +45 -42
- package/src/commands/code/__tests__/fake-file-store.ts +32 -23
- package/src/commands/code/__tests__/fake-prompter.ts +116 -77
- package/src/commands/code/__tests__/setup-flow.test.ts +624 -268
- package/src/commands/code/adapters/clack-prompter.ts +53 -39
- package/src/commands/code/adapters/fs-file-store.ts +32 -27
- package/src/commands/code/adapters/spawn-command-runner.ts +38 -29
- package/src/commands/code/auth-sync.ts +329 -0
- package/src/commands/code/errors.ts +18 -18
- package/src/commands/code/ports/auth-services.ts +14 -0
- package/src/commands/code/ports/command-runner.ts +8 -4
- package/src/commands/code/ports/file-store.ts +5 -4
- package/src/commands/code/ports/prompter.ts +24 -18
- package/src/commands/code/setup.ts +570 -340
- package/src/commands/code.ts +338 -539
- package/src/commands/index.ts +20 -19
- package/src/commands/models.ts +28 -32
- package/src/commands/users.ts +15 -21
- package/src/constants/command-structure.ts +134 -157
- package/src/services/api-key-service.ts +105 -122
- package/src/services/auth-service.ts +99 -345
- package/src/services/browser-auth.ts +296 -0
- package/src/services/chat-service.ts +265 -299
- package/src/services/cluster-service.ts +42 -45
- package/src/services/collaborator-service.ts +14 -19
- package/src/services/flux-service.ts +23 -25
- package/src/services/helm-service.ts +19 -21
- package/src/services/kubectl-service.ts +17 -19
- package/src/types/api.d.ts +1905 -1907
- package/src/types/json.d.ts +2 -2
- package/src/utils/config-checker.ts +10 -10
- package/src/utils/config-loader.ts +162 -178
- package/src/utils/default-api-key.ts +114 -125
- package/src/utils/env-manager.ts +53 -57
- package/src/utils/error-handler.ts +61 -56
- package/src/utils/logger.ts +79 -73
- package/src/utils/markdown-renderer.ts +31 -31
- package/src/utils/opencode-validator.ts +85 -89
- package/src/utils/token-manager.ts +108 -87
- package/templates/agents/app.md +1 -0
- package/templates/agents/backend.md +1 -0
- package/templates/agents/devops.md +2 -0
- package/templates/agents/frontend.md +1 -0
- package/templates/agents/fullstack.md +1 -0
- package/templates/agents/quality.md +45 -40
- package/templates/agents/security.md +1 -0
- package/tests/commands/chat.test.ts +53 -62
- package/tests/commands/code.test.ts +265 -310
- package/tests/utils/config-loader.test.ts +189 -188
- package/tests/utils/env-manager.test.ts +110 -113
- package/tests/utils/opencode-validator.test.ts +52 -56
- package/tsconfig.json +4 -3
- package/vitest.config.ts +3 -3
- package/AGENTS.md +0 -374
- package/TODO.md +0 -19
package/src/types/json.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import * as fs from 'fs'
|
|
2
|
-
import * as path from 'path'
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Check for .bergetconfig file and handle cluster switching
|
|
6
6
|
*/
|
|
7
7
|
export function checkBergetConfig(): void {
|
|
8
|
-
const configPath = path.join(process.cwd(), '.bergetconfig')
|
|
8
|
+
const configPath = path.join(process.cwd(), '.bergetconfig');
|
|
9
9
|
if (fs.existsSync(configPath)) {
|
|
10
10
|
try {
|
|
11
|
-
const config = fs.readFileSync(configPath, 'utf8')
|
|
12
|
-
const match = config.match(/cluster:\s*(.+)/)
|
|
11
|
+
const config = fs.readFileSync(configPath, 'utf8');
|
|
12
|
+
const match = config.match(/cluster:\s*(.+)/);
|
|
13
13
|
if (match && match[1]) {
|
|
14
|
-
const clusterName = match[1].trim()
|
|
15
|
-
console.log(`🔄 Berget: Switched to cluster "${clusterName}"`)
|
|
16
|
-
console.log('✓ kubectl config updated')
|
|
17
|
-
console.log('')
|
|
14
|
+
const clusterName = match[1].trim();
|
|
15
|
+
console.log(`🔄 Berget: Switched to cluster "${clusterName}"`);
|
|
16
|
+
console.log('✓ kubectl config updated');
|
|
17
|
+
console.log('');
|
|
18
18
|
}
|
|
19
|
-
} catch
|
|
19
|
+
} catch {
|
|
20
20
|
// Silently ignore errors reading config
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import * as fs from 'fs'
|
|
2
|
-
import * as path from 'path'
|
|
3
|
-
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { logger } from './logger';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Centralized agent configuration loader
|
|
@@ -8,104 +9,73 @@ import { logger } from './logger'
|
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
export interface AgentConfig {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
description?: string;
|
|
13
|
+
mode: 'primary' | 'subagent';
|
|
14
|
+
model: string;
|
|
15
|
+
note?: string;
|
|
15
16
|
permission: {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
webfetch: 'allow' | 'deny'
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
bash: 'allow' | 'deny';
|
|
18
|
+
edit: 'allow' | 'deny';
|
|
19
|
+
webfetch: 'allow' | 'deny';
|
|
20
|
+
};
|
|
21
|
+
prompt?: string;
|
|
22
|
+
temperature: number;
|
|
23
|
+
top_p: number;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export interface ModelConfig {
|
|
26
|
-
primary: string
|
|
27
|
-
small: string
|
|
27
|
+
primary: string;
|
|
28
|
+
small: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface OpenCodeConfig {
|
|
32
|
+
$schema?: string;
|
|
33
|
+
agent?: Record<string, AgentConfig>;
|
|
34
|
+
autoupdate?: boolean;
|
|
35
|
+
command?: Record<string, any>;
|
|
36
|
+
model?: string;
|
|
37
|
+
provider?: Record<string, any>;
|
|
38
|
+
share?: string;
|
|
39
|
+
small_model?: string;
|
|
40
|
+
theme?: string;
|
|
41
|
+
username?: string;
|
|
42
|
+
watcher?: Record<string, any>;
|
|
28
43
|
}
|
|
29
44
|
|
|
30
45
|
export interface ProviderModelConfig {
|
|
31
|
-
name: string
|
|
32
46
|
limit: {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
47
|
+
context: number;
|
|
48
|
+
output: number;
|
|
49
|
+
};
|
|
36
50
|
modalities?: {
|
|
37
|
-
input: string[]
|
|
38
|
-
output: string[]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export interface OpenCodeConfig {
|
|
43
|
-
$schema?: string
|
|
44
|
-
username?: string
|
|
45
|
-
theme?: string
|
|
46
|
-
share?: string
|
|
47
|
-
autoupdate?: boolean
|
|
48
|
-
model?: string
|
|
49
|
-
small_model?: string
|
|
50
|
-
agent?: Record<string, AgentConfig>
|
|
51
|
-
command?: Record<string, any>
|
|
52
|
-
watcher?: Record<string, any>
|
|
53
|
-
provider?: Record<string, any>
|
|
51
|
+
input: string[];
|
|
52
|
+
output: string[];
|
|
53
|
+
};
|
|
54
|
+
name: string;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export class ConfigLoader {
|
|
57
|
-
private static instance: ConfigLoader
|
|
58
|
-
private config:
|
|
59
|
-
private configPath: string
|
|
58
|
+
private static instance: ConfigLoader;
|
|
59
|
+
private config: null | OpenCodeConfig = null;
|
|
60
|
+
private configPath: string;
|
|
60
61
|
|
|
61
62
|
private constructor(configPath?: string) {
|
|
62
63
|
// Default to opencode.json in current working directory
|
|
63
|
-
this.configPath = configPath || path.join(process.cwd(), 'opencode.json')
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public static getInstance(configPath?: string): ConfigLoader {
|
|
67
|
-
if (!ConfigLoader.instance) {
|
|
68
|
-
ConfigLoader.instance = new ConfigLoader(configPath)
|
|
69
|
-
}
|
|
70
|
-
return ConfigLoader.instance
|
|
64
|
+
this.configPath = configPath || path.join(process.cwd(), 'opencode.json');
|
|
71
65
|
}
|
|
72
66
|
|
|
73
67
|
/**
|
|
74
68
|
* Clear the singleton instance (for testing purposes)
|
|
75
69
|
*/
|
|
76
70
|
public static clearInstance(): void {
|
|
77
|
-
ConfigLoader.instance = null as any
|
|
71
|
+
ConfigLoader.instance = null as any;
|
|
78
72
|
}
|
|
79
73
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
public loadConfig(): OpenCodeConfig {
|
|
84
|
-
if (this.config) {
|
|
85
|
-
return this.config
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
if (!fs.existsSync(this.configPath)) {
|
|
90
|
-
throw new Error(`Configuration file not found: ${this.configPath}`)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const configContent = fs.readFileSync(this.configPath, 'utf8')
|
|
94
|
-
this.config = JSON.parse(configContent) as OpenCodeConfig
|
|
95
|
-
|
|
96
|
-
logger.debug(`Loaded configuration from ${this.configPath}`)
|
|
97
|
-
return this.config
|
|
98
|
-
} catch (error) {
|
|
99
|
-
logger.error(
|
|
100
|
-
`Failed to load configuration from ${this.configPath}:`,
|
|
101
|
-
error
|
|
102
|
-
)
|
|
103
|
-
throw new Error(
|
|
104
|
-
`Failed to load configuration: ${
|
|
105
|
-
error instanceof Error ? error.message : String(error)
|
|
106
|
-
}`
|
|
107
|
-
)
|
|
74
|
+
public static getInstance(configPath?: string): ConfigLoader {
|
|
75
|
+
if (!ConfigLoader.instance) {
|
|
76
|
+
ConfigLoader.instance = new ConfigLoader(configPath);
|
|
108
77
|
}
|
|
78
|
+
return ConfigLoader.instance;
|
|
109
79
|
}
|
|
110
80
|
|
|
111
81
|
/**
|
|
@@ -113,45 +83,93 @@ export class ConfigLoader {
|
|
|
113
83
|
*/
|
|
114
84
|
public getAgentConfig(agentName: string): AgentConfig | null {
|
|
115
85
|
try {
|
|
116
|
-
const config = this.loadConfig()
|
|
117
|
-
return config.agent?.[agentName] || null
|
|
118
|
-
} catch
|
|
86
|
+
const config = this.loadConfig();
|
|
87
|
+
return config.agent?.[agentName] || null;
|
|
88
|
+
} catch {
|
|
119
89
|
// Config file doesn't exist, return null
|
|
120
|
-
return null
|
|
90
|
+
return null;
|
|
121
91
|
}
|
|
122
92
|
}
|
|
123
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Get list of all available agent names
|
|
96
|
+
*/
|
|
97
|
+
public getAgentNames(): string[] {
|
|
98
|
+
return Object.keys(this.getAllAgentConfigs());
|
|
99
|
+
}
|
|
100
|
+
|
|
124
101
|
/**
|
|
125
102
|
* Get all agent configurations
|
|
126
103
|
*/
|
|
127
104
|
public getAllAgentConfigs(): Record<string, AgentConfig> {
|
|
128
105
|
try {
|
|
129
|
-
const config = this.loadConfig()
|
|
130
|
-
return config.agent || {}
|
|
131
|
-
} catch
|
|
106
|
+
const config = this.loadConfig();
|
|
107
|
+
return config.agent || {};
|
|
108
|
+
} catch {
|
|
132
109
|
// Config file doesn't exist, return empty object
|
|
133
|
-
return {}
|
|
110
|
+
return {};
|
|
134
111
|
}
|
|
135
112
|
}
|
|
136
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Get command configurations
|
|
116
|
+
*/
|
|
117
|
+
public getCommandConfigs(): Record<string, any> {
|
|
118
|
+
try {
|
|
119
|
+
const config = this.loadConfig();
|
|
120
|
+
return config.command || {};
|
|
121
|
+
} catch {
|
|
122
|
+
// Config file doesn't exist, return empty object
|
|
123
|
+
return {};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get the current configuration path
|
|
129
|
+
*/
|
|
130
|
+
public getConfigPath(): string {
|
|
131
|
+
return this.configPath;
|
|
132
|
+
}
|
|
133
|
+
|
|
137
134
|
/**
|
|
138
135
|
* Get model configuration
|
|
139
136
|
*/
|
|
140
137
|
public getModelConfig(): ModelConfig {
|
|
141
138
|
try {
|
|
142
|
-
const config = this.loadConfig()
|
|
139
|
+
const config = this.loadConfig();
|
|
143
140
|
|
|
144
141
|
// Extract from config or fall back to defaults
|
|
145
|
-
const primary = config.model || 'berget/glm-4.7'
|
|
146
|
-
const small = config.small_model || 'berget/gpt-oss'
|
|
142
|
+
const primary = config.model || 'berget/glm-4.7';
|
|
143
|
+
const small = config.small_model || 'berget/gpt-oss';
|
|
147
144
|
|
|
148
|
-
return { primary, small }
|
|
149
|
-
} catch
|
|
145
|
+
return { primary, small };
|
|
146
|
+
} catch {
|
|
150
147
|
// Fallback to defaults when no config exists (init scenario)
|
|
151
148
|
return {
|
|
152
149
|
primary: 'berget/glm-4.7',
|
|
153
150
|
small: 'berget/gpt-oss',
|
|
154
|
-
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get list of primary agents (mode: 'primary')
|
|
157
|
+
*/
|
|
158
|
+
public getPrimaryAgentNames(): string[] {
|
|
159
|
+
const agents = this.getAllAgentConfigs();
|
|
160
|
+
return Object.keys(agents).filter((name) => agents[name].mode === 'primary');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Get provider configuration
|
|
165
|
+
*/
|
|
166
|
+
public getProviderConfig(): Record<string, any> {
|
|
167
|
+
try {
|
|
168
|
+
const config = this.loadConfig();
|
|
169
|
+
return config.provider || {};
|
|
170
|
+
} catch {
|
|
171
|
+
// Config file doesn't exist, return empty object
|
|
172
|
+
return {};
|
|
155
173
|
}
|
|
156
174
|
}
|
|
157
175
|
|
|
@@ -160,51 +178,43 @@ export class ConfigLoader {
|
|
|
160
178
|
*/
|
|
161
179
|
public getProviderModels(): Record<string, ProviderModelConfig> {
|
|
162
180
|
try {
|
|
163
|
-
const config = this.loadConfig()
|
|
181
|
+
const config = this.loadConfig();
|
|
164
182
|
|
|
165
183
|
// Extract from provider configuration
|
|
166
184
|
if (config.provider?.berget?.models) {
|
|
167
|
-
return config.provider.berget.models as Record<
|
|
168
|
-
string,
|
|
169
|
-
ProviderModelConfig
|
|
170
|
-
>
|
|
185
|
+
return config.provider.berget.models as Record<string, ProviderModelConfig>;
|
|
171
186
|
}
|
|
172
|
-
} catch
|
|
187
|
+
} catch {
|
|
173
188
|
// Config file doesn't exist, use fallback defaults
|
|
174
189
|
}
|
|
175
190
|
|
|
176
191
|
// Fallback to defaults
|
|
177
192
|
return {
|
|
178
193
|
'glm-4.7': {
|
|
194
|
+
limit: { context: 90_000, output: 4000 },
|
|
179
195
|
name: 'GLM-4.7',
|
|
180
|
-
limit: { output: 4000, context: 90000 },
|
|
181
196
|
},
|
|
182
197
|
'gpt-oss': {
|
|
183
|
-
|
|
184
|
-
limit: { output: 4000, context: 128000 },
|
|
198
|
+
limit: { context: 128_000, output: 4000 },
|
|
185
199
|
modalities: {
|
|
186
200
|
input: ['text', 'image'],
|
|
187
201
|
output: ['text'],
|
|
188
202
|
},
|
|
203
|
+
name: 'GPT-OSS',
|
|
189
204
|
},
|
|
190
205
|
'llama-8b': {
|
|
206
|
+
limit: { context: 128_000, output: 4000 },
|
|
191
207
|
name: 'llama-3.1-8b',
|
|
192
|
-
limit: { output: 4000, context: 128000 },
|
|
193
208
|
},
|
|
194
|
-
}
|
|
209
|
+
};
|
|
195
210
|
}
|
|
196
211
|
|
|
197
212
|
/**
|
|
198
|
-
* Get
|
|
213
|
+
* Get list of subagents (mode: 'subagent')
|
|
199
214
|
*/
|
|
200
|
-
public
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
return config.command || {}
|
|
204
|
-
} catch (error) {
|
|
205
|
-
// Config file doesn't exist, return empty object
|
|
206
|
-
return {}
|
|
207
|
-
}
|
|
215
|
+
public getSubagentNames(): string[] {
|
|
216
|
+
const agents = this.getAllAgentConfigs();
|
|
217
|
+
return Object.keys(agents).filter((name) => agents[name].mode === 'subagent');
|
|
208
218
|
}
|
|
209
219
|
|
|
210
220
|
/**
|
|
@@ -212,28 +222,15 @@ export class ConfigLoader {
|
|
|
212
222
|
*/
|
|
213
223
|
public getWatcherConfig(): Record<string, any> {
|
|
214
224
|
try {
|
|
215
|
-
const config = this.loadConfig()
|
|
225
|
+
const config = this.loadConfig();
|
|
216
226
|
return (
|
|
217
227
|
config.watcher || {
|
|
218
228
|
ignore: ['node_modules', 'dist', '.git', 'coverage'],
|
|
219
229
|
}
|
|
220
|
-
)
|
|
221
|
-
} catch
|
|
230
|
+
);
|
|
231
|
+
} catch {
|
|
222
232
|
// Config file doesn't exist, return default watcher config
|
|
223
|
-
return { ignore: ['node_modules', 'dist', '.git', 'coverage'] }
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Get provider configuration
|
|
229
|
-
*/
|
|
230
|
-
public getProviderConfig(): Record<string, any> {
|
|
231
|
-
try {
|
|
232
|
-
const config = this.loadConfig()
|
|
233
|
-
return config.provider || {}
|
|
234
|
-
} catch (error) {
|
|
235
|
-
// Config file doesn't exist, return empty object
|
|
236
|
-
return {}
|
|
233
|
+
return { ignore: ['node_modules', 'dist', '.git', 'coverage'] };
|
|
237
234
|
}
|
|
238
235
|
}
|
|
239
236
|
|
|
@@ -241,96 +238,83 @@ export class ConfigLoader {
|
|
|
241
238
|
* Check if an agent exists
|
|
242
239
|
*/
|
|
243
240
|
public hasAgent(agentName: string): boolean {
|
|
244
|
-
return agentName in this.getAllAgentConfigs()
|
|
241
|
+
return agentName in this.getAllAgentConfigs();
|
|
245
242
|
}
|
|
246
243
|
|
|
247
244
|
/**
|
|
248
|
-
*
|
|
245
|
+
* Load configuration from opencode.json
|
|
249
246
|
*/
|
|
250
|
-
public
|
|
251
|
-
|
|
252
|
-
|
|
247
|
+
public loadConfig(): OpenCodeConfig {
|
|
248
|
+
if (this.config) {
|
|
249
|
+
return this.config;
|
|
250
|
+
}
|
|
253
251
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const agents = this.getAllAgentConfigs()
|
|
259
|
-
return Object.keys(agents).filter((name) => agents[name].mode === 'primary')
|
|
260
|
-
}
|
|
252
|
+
try {
|
|
253
|
+
if (!fs.existsSync(this.configPath)) {
|
|
254
|
+
throw new Error(`Configuration file not found: ${this.configPath}`);
|
|
255
|
+
}
|
|
261
256
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
(
|
|
269
|
-
|
|
257
|
+
const configContent = fs.readFileSync(this.configPath, 'utf8');
|
|
258
|
+
this.config = JSON.parse(configContent) as OpenCodeConfig;
|
|
259
|
+
|
|
260
|
+
logger.debug(`Loaded configuration from ${this.configPath}`);
|
|
261
|
+
return this.config;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
logger.error(`Failed to load configuration from ${this.configPath}:`, error);
|
|
264
|
+
throw new Error(
|
|
265
|
+
`Failed to load configuration: ${error instanceof Error ? error.message : String(error)}`,
|
|
266
|
+
);
|
|
267
|
+
}
|
|
270
268
|
}
|
|
271
269
|
|
|
272
270
|
/**
|
|
273
271
|
* Reload configuration from file
|
|
274
272
|
*/
|
|
275
273
|
public reloadConfig(): OpenCodeConfig {
|
|
276
|
-
this.config = null
|
|
277
|
-
return this.loadConfig()
|
|
274
|
+
this.config = null;
|
|
275
|
+
return this.loadConfig();
|
|
278
276
|
}
|
|
279
277
|
|
|
280
278
|
/**
|
|
281
279
|
* Set custom configuration path (for testing or different environments)
|
|
282
280
|
*/
|
|
283
281
|
public setConfigPath(configPath: string): void {
|
|
284
|
-
this.configPath = configPath
|
|
285
|
-
this.config = null // Force reload
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Get the current configuration path
|
|
290
|
-
*/
|
|
291
|
-
public getConfigPath(): string {
|
|
292
|
-
return this.configPath
|
|
282
|
+
this.configPath = configPath;
|
|
283
|
+
this.config = null; // Force reload
|
|
293
284
|
}
|
|
294
285
|
}
|
|
295
286
|
|
|
296
287
|
/**
|
|
297
|
-
* Convenience function to get
|
|
288
|
+
* Convenience function to get agent configuration
|
|
298
289
|
*/
|
|
299
|
-
export function
|
|
300
|
-
return
|
|
290
|
+
export function getAgentConfig(agentName: string, configPath?: string): AgentConfig | null {
|
|
291
|
+
return getConfigLoader(configPath).getAgentConfig(agentName);
|
|
301
292
|
}
|
|
302
293
|
|
|
303
294
|
/**
|
|
304
|
-
* Convenience function to get agent
|
|
295
|
+
* Convenience function to get all agent configurations
|
|
305
296
|
*/
|
|
306
|
-
export function
|
|
307
|
-
|
|
308
|
-
configPath?: string
|
|
309
|
-
): AgentConfig | null {
|
|
310
|
-
return getConfigLoader(configPath).getAgentConfig(agentName)
|
|
297
|
+
export function getAllAgentConfigs(configPath?: string): Record<string, AgentConfig> {
|
|
298
|
+
return getConfigLoader(configPath).getAllAgentConfigs();
|
|
311
299
|
}
|
|
312
300
|
|
|
313
301
|
/**
|
|
314
|
-
* Convenience function to get
|
|
302
|
+
* Convenience function to get the config loader instance
|
|
315
303
|
*/
|
|
316
|
-
export function
|
|
317
|
-
configPath
|
|
318
|
-
): Record<string, AgentConfig> {
|
|
319
|
-
return getConfigLoader(configPath).getAllAgentConfigs()
|
|
304
|
+
export function getConfigLoader(configPath?: string): ConfigLoader {
|
|
305
|
+
return ConfigLoader.getInstance(configPath);
|
|
320
306
|
}
|
|
321
307
|
|
|
322
308
|
/**
|
|
323
309
|
* Convenience function to get model configuration
|
|
324
310
|
*/
|
|
325
311
|
export function getModelConfig(configPath?: string): ModelConfig {
|
|
326
|
-
return getConfigLoader(configPath).getModelConfig()
|
|
312
|
+
return getConfigLoader(configPath).getModelConfig();
|
|
327
313
|
}
|
|
328
314
|
|
|
329
315
|
/**
|
|
330
316
|
* Convenience function to get provider models
|
|
331
317
|
*/
|
|
332
|
-
export function getProviderModels(
|
|
333
|
-
configPath
|
|
334
|
-
): Record<string, ProviderModelConfig> {
|
|
335
|
-
return getConfigLoader(configPath).getProviderModels()
|
|
318
|
+
export function getProviderModels(configPath?: string): Record<string, ProviderModelConfig> {
|
|
319
|
+
return getConfigLoader(configPath).getProviderModels();
|
|
336
320
|
}
|