fraim 2.0.100
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/README.md +445 -0
- package/bin/fraim.js +23 -0
- package/dist/src/cli/api/get-provider-client.js +41 -0
- package/dist/src/cli/api/provider-client.js +107 -0
- package/dist/src/cli/commands/add-ide.js +430 -0
- package/dist/src/cli/commands/add-provider.js +233 -0
- package/dist/src/cli/commands/doctor.js +149 -0
- package/dist/src/cli/commands/init-project.js +301 -0
- package/dist/src/cli/commands/list-overridable.js +184 -0
- package/dist/src/cli/commands/list.js +57 -0
- package/dist/src/cli/commands/login.js +84 -0
- package/dist/src/cli/commands/mcp.js +15 -0
- package/dist/src/cli/commands/migrate-project-fraim.js +42 -0
- package/dist/src/cli/commands/override.js +177 -0
- package/dist/src/cli/commands/setup.js +651 -0
- package/dist/src/cli/commands/sync.js +162 -0
- package/dist/src/cli/commands/test-mcp.js +171 -0
- package/dist/src/cli/doctor/check-runner.js +199 -0
- package/dist/src/cli/doctor/checks/global-setup-checks.js +220 -0
- package/dist/src/cli/doctor/checks/ide-config-checks.js +250 -0
- package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +381 -0
- package/dist/src/cli/doctor/checks/project-setup-checks.js +282 -0
- package/dist/src/cli/doctor/checks/scripts-checks.js +157 -0
- package/dist/src/cli/doctor/checks/workflow-checks.js +251 -0
- package/dist/src/cli/doctor/reporters/console-reporter.js +96 -0
- package/dist/src/cli/doctor/reporters/json-reporter.js +11 -0
- package/dist/src/cli/doctor/types.js +6 -0
- package/dist/src/cli/fraim.js +100 -0
- package/dist/src/cli/internal/device-flow-service.js +83 -0
- package/dist/src/cli/mcp/ide-formats.js +243 -0
- package/dist/src/cli/mcp/mcp-server-builder.js +48 -0
- package/dist/src/cli/mcp/mcp-server-registry.js +160 -0
- package/dist/src/cli/mcp/types.js +3 -0
- package/dist/src/cli/providers/local-provider-registry.js +166 -0
- package/dist/src/cli/providers/provider-registry.js +230 -0
- package/dist/src/cli/setup/auto-mcp-setup.js +331 -0
- package/dist/src/cli/setup/codex-local-config.js +37 -0
- package/dist/src/cli/setup/first-run.js +242 -0
- package/dist/src/cli/setup/ide-detector.js +179 -0
- package/dist/src/cli/setup/mcp-config-generator.js +192 -0
- package/dist/src/cli/setup/provider-prompts.js +339 -0
- package/dist/src/cli/utils/agent-adapters.js +126 -0
- package/dist/src/cli/utils/digest-utils.js +47 -0
- package/dist/src/cli/utils/fraim-gitignore.js +40 -0
- package/dist/src/cli/utils/platform-detection.js +258 -0
- package/dist/src/cli/utils/project-bootstrap.js +93 -0
- package/dist/src/cli/utils/remote-sync.js +315 -0
- package/dist/src/cli/utils/script-sync-utils.js +221 -0
- package/dist/src/cli/utils/version-utils.js +32 -0
- package/dist/src/core/ai-mentor.js +230 -0
- package/dist/src/core/config-loader.js +114 -0
- package/dist/src/core/config-writer.js +75 -0
- package/dist/src/core/types.js +23 -0
- package/dist/src/core/utils/git-utils.js +95 -0
- package/dist/src/core/utils/include-resolver.js +92 -0
- package/dist/src/core/utils/inheritance-parser.js +288 -0
- package/dist/src/core/utils/job-parser.js +176 -0
- package/dist/src/core/utils/local-registry-resolver.js +616 -0
- package/dist/src/core/utils/object-utils.js +11 -0
- package/dist/src/core/utils/project-fraim-migration.js +103 -0
- package/dist/src/core/utils/project-fraim-paths.js +38 -0
- package/dist/src/core/utils/provider-utils.js +18 -0
- package/dist/src/core/utils/server-startup.js +34 -0
- package/dist/src/core/utils/stub-generator.js +147 -0
- package/dist/src/core/utils/workflow-parser.js +174 -0
- package/dist/src/local-mcp-server/learning-context-builder.js +229 -0
- package/dist/src/local-mcp-server/stdio-server.js +1698 -0
- package/dist/src/local-mcp-server/usage-collector.js +264 -0
- package/index.js +85 -0
- package/package.json +139 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Global setup checks for FRAIM doctor command
|
|
4
|
+
* Validates global configuration and API keys
|
|
5
|
+
* Issue #144: Enhanced doctor command
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.getGlobalSetupChecks = getGlobalSetupChecks;
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const os_1 = __importDefault(require("os"));
|
|
15
|
+
const getGlobalConfigPath = () => path_1.default.join(os_1.default.homedir(), '.fraim', 'config.json');
|
|
16
|
+
/**
|
|
17
|
+
* Check if global config exists
|
|
18
|
+
*/
|
|
19
|
+
function checkGlobalConfigExists() {
|
|
20
|
+
return {
|
|
21
|
+
name: 'Global config exists',
|
|
22
|
+
category: 'globalSetup',
|
|
23
|
+
critical: true,
|
|
24
|
+
run: async () => {
|
|
25
|
+
if (fs_1.default.existsSync(getGlobalConfigPath())) {
|
|
26
|
+
return {
|
|
27
|
+
status: 'passed',
|
|
28
|
+
message: 'Global config exists',
|
|
29
|
+
details: { path: getGlobalConfigPath() }
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
status: 'error',
|
|
34
|
+
message: 'Global config missing',
|
|
35
|
+
suggestion: 'Run fraim setup to create global configuration',
|
|
36
|
+
command: 'fraim setup'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if mode is valid
|
|
43
|
+
*/
|
|
44
|
+
function checkModeValid() {
|
|
45
|
+
return {
|
|
46
|
+
name: 'Mode valid',
|
|
47
|
+
category: 'globalSetup',
|
|
48
|
+
critical: false,
|
|
49
|
+
run: async () => {
|
|
50
|
+
try {
|
|
51
|
+
if (!fs_1.default.existsSync(getGlobalConfigPath())) {
|
|
52
|
+
return {
|
|
53
|
+
status: 'error',
|
|
54
|
+
message: 'Cannot check mode - global config missing'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const config = JSON.parse(fs_1.default.readFileSync(getGlobalConfigPath(), 'utf8'));
|
|
58
|
+
const mode = config.mode || 'conversational';
|
|
59
|
+
const validModes = ['conversational', 'integrated', 'split'];
|
|
60
|
+
if (validModes.includes(mode)) {
|
|
61
|
+
return {
|
|
62
|
+
status: 'passed',
|
|
63
|
+
message: `Mode: ${mode}`,
|
|
64
|
+
details: { mode }
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
status: 'error',
|
|
69
|
+
message: `Invalid mode: ${mode}`,
|
|
70
|
+
suggestion: 'Mode must be conversational, integrated, or split',
|
|
71
|
+
details: { mode, validModes }
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return {
|
|
76
|
+
status: 'error',
|
|
77
|
+
message: 'Failed to read mode from config',
|
|
78
|
+
details: { error: error.message }
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if API key is configured
|
|
86
|
+
*/
|
|
87
|
+
function checkApiKeyConfigured() {
|
|
88
|
+
return {
|
|
89
|
+
name: 'API key configured',
|
|
90
|
+
category: 'globalSetup',
|
|
91
|
+
critical: false,
|
|
92
|
+
run: async () => {
|
|
93
|
+
try {
|
|
94
|
+
if (!fs_1.default.existsSync(getGlobalConfigPath())) {
|
|
95
|
+
return {
|
|
96
|
+
status: 'error',
|
|
97
|
+
message: 'Cannot check API key - global config missing'
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const config = JSON.parse(fs_1.default.readFileSync(getGlobalConfigPath(), 'utf8'));
|
|
101
|
+
if (config.apiKey) {
|
|
102
|
+
const maskedKey = config.apiKey.substring(0, 10) + '...';
|
|
103
|
+
return {
|
|
104
|
+
status: 'passed',
|
|
105
|
+
message: `API key configured (${maskedKey})`,
|
|
106
|
+
details: { keyPrefix: config.apiKey.substring(0, 10) }
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
status: 'warning',
|
|
111
|
+
message: 'API key not configured',
|
|
112
|
+
suggestion: 'Add apiKey to global config for remote features',
|
|
113
|
+
details: { configPath: getGlobalConfigPath() }
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
status: 'error',
|
|
119
|
+
message: 'Failed to read API key from config',
|
|
120
|
+
details: { error: error.message }
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check if GitHub token is configured
|
|
128
|
+
*/
|
|
129
|
+
function checkGitHubTokenConfigured() {
|
|
130
|
+
return {
|
|
131
|
+
name: 'GitHub token configured',
|
|
132
|
+
category: 'globalSetup',
|
|
133
|
+
critical: false,
|
|
134
|
+
run: async () => {
|
|
135
|
+
try {
|
|
136
|
+
if (!fs_1.default.existsSync(getGlobalConfigPath())) {
|
|
137
|
+
return {
|
|
138
|
+
status: 'error',
|
|
139
|
+
message: 'Cannot check GitHub token - global config missing'
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const config = JSON.parse(fs_1.default.readFileSync(getGlobalConfigPath(), 'utf8'));
|
|
143
|
+
// Check if repository provider is GitHub
|
|
144
|
+
if (config.repository?.provider === 'github') {
|
|
145
|
+
// Token would be in IDE MCP configs, not global config
|
|
146
|
+
return {
|
|
147
|
+
status: 'passed',
|
|
148
|
+
message: 'GitHub provider configured',
|
|
149
|
+
details: { provider: 'github' }
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
status: 'passed',
|
|
154
|
+
message: 'GitHub not configured (not required)',
|
|
155
|
+
details: { provider: config.repository?.provider || 'none' }
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return {
|
|
160
|
+
status: 'error',
|
|
161
|
+
message: 'Failed to check GitHub configuration',
|
|
162
|
+
details: { error: error.message }
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Check if remote URL is configured (optional)
|
|
170
|
+
*/
|
|
171
|
+
function checkRemoteUrlConfigured() {
|
|
172
|
+
return {
|
|
173
|
+
name: 'Remote URL configured',
|
|
174
|
+
category: 'globalSetup',
|
|
175
|
+
critical: false,
|
|
176
|
+
run: async () => {
|
|
177
|
+
try {
|
|
178
|
+
if (!fs_1.default.existsSync(getGlobalConfigPath())) {
|
|
179
|
+
return {
|
|
180
|
+
status: 'error',
|
|
181
|
+
message: 'Cannot check remote URL - global config missing'
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const config = JSON.parse(fs_1.default.readFileSync(getGlobalConfigPath(), 'utf8'));
|
|
185
|
+
if (config.remoteUrl) {
|
|
186
|
+
return {
|
|
187
|
+
status: 'passed',
|
|
188
|
+
message: `Remote URL: ${config.remoteUrl}`,
|
|
189
|
+
details: { remoteUrl: config.remoteUrl }
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
// Remote URL is optional - just note it's not configured
|
|
193
|
+
return {
|
|
194
|
+
status: 'passed',
|
|
195
|
+
message: 'Remote URL not configured (optional)',
|
|
196
|
+
details: { configPath: getGlobalConfigPath(), optional: true }
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
return {
|
|
201
|
+
status: 'error',
|
|
202
|
+
message: 'Failed to read remote URL from config',
|
|
203
|
+
details: { error: error.message }
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get all global setup checks
|
|
211
|
+
*/
|
|
212
|
+
function getGlobalSetupChecks() {
|
|
213
|
+
return [
|
|
214
|
+
checkGlobalConfigExists(),
|
|
215
|
+
checkModeValid(),
|
|
216
|
+
checkApiKeyConfigured(),
|
|
217
|
+
checkGitHubTokenConfigured(),
|
|
218
|
+
checkRemoteUrlConfigured()
|
|
219
|
+
];
|
|
220
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IDE configuration checks for FRAIM doctor command
|
|
4
|
+
* Validates IDE installations and MCP configurations
|
|
5
|
+
* Issue #144: Enhanced doctor command
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.getIDEConfigChecks = getIDEConfigChecks;
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const ide_detector_1 = require("../../setup/ide-detector");
|
|
14
|
+
/**
|
|
15
|
+
* Check if any IDEs are detected
|
|
16
|
+
*/
|
|
17
|
+
function checkIDEsDetected() {
|
|
18
|
+
return {
|
|
19
|
+
name: 'IDEs detected',
|
|
20
|
+
category: 'ideConfiguration',
|
|
21
|
+
critical: false,
|
|
22
|
+
run: async () => {
|
|
23
|
+
const installedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
24
|
+
if (installedIDEs.length > 0) {
|
|
25
|
+
const ideNames = installedIDEs.map(ide => ide.name).join(', ');
|
|
26
|
+
return {
|
|
27
|
+
status: 'passed',
|
|
28
|
+
message: `${installedIDEs.length} IDE(s) detected: ${ideNames}`,
|
|
29
|
+
details: {
|
|
30
|
+
count: installedIDEs.length,
|
|
31
|
+
ides: installedIDEs.map(ide => ide.name)
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
status: 'warning',
|
|
37
|
+
message: 'No IDEs detected',
|
|
38
|
+
suggestion: 'Install Claude Desktop, Cursor, or another supported IDE',
|
|
39
|
+
details: { supportedIDEs: ['Claude Desktop', 'Cursor', 'Windsurf', 'VS Code', 'Zed', 'Codex'] }
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if MCP configs exist for detected IDEs
|
|
46
|
+
*/
|
|
47
|
+
function checkMCPConfigsExist() {
|
|
48
|
+
return {
|
|
49
|
+
name: 'MCP configs exist',
|
|
50
|
+
category: 'ideConfiguration',
|
|
51
|
+
critical: false,
|
|
52
|
+
run: async () => {
|
|
53
|
+
const installedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
54
|
+
if (installedIDEs.length === 0) {
|
|
55
|
+
return {
|
|
56
|
+
status: 'warning',
|
|
57
|
+
message: 'No IDEs detected to check configs'
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
let existCount = 0;
|
|
61
|
+
let missingCount = 0;
|
|
62
|
+
const missing = [];
|
|
63
|
+
for (const ide of installedIDEs) {
|
|
64
|
+
const configPath = (0, ide_detector_1.expandPath)(ide.configPath);
|
|
65
|
+
if (fs_1.default.existsSync(configPath)) {
|
|
66
|
+
existCount++;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
missingCount++;
|
|
70
|
+
missing.push(ide.name);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (missingCount === 0) {
|
|
74
|
+
return {
|
|
75
|
+
status: 'passed',
|
|
76
|
+
message: `MCP configs exist for all ${existCount} IDE(s)`,
|
|
77
|
+
details: { existCount }
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (existCount > 0) {
|
|
81
|
+
return {
|
|
82
|
+
status: 'warning',
|
|
83
|
+
message: `MCP configs missing for ${missingCount} IDE(s): ${missing.join(', ')}`,
|
|
84
|
+
suggestion: 'Run fraim add-ide to configure MCP servers',
|
|
85
|
+
command: 'fraim add-ide',
|
|
86
|
+
details: { existCount, missingCount, missing }
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
status: 'error',
|
|
91
|
+
message: 'No MCP configs found',
|
|
92
|
+
suggestion: 'Run fraim add-ide to configure MCP servers',
|
|
93
|
+
command: 'fraim add-ide'
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if MCP configs are valid JSON/TOML
|
|
100
|
+
*/
|
|
101
|
+
function checkMCPConfigsValid() {
|
|
102
|
+
return {
|
|
103
|
+
name: 'MCP configs valid',
|
|
104
|
+
category: 'ideConfiguration',
|
|
105
|
+
critical: false,
|
|
106
|
+
run: async () => {
|
|
107
|
+
const installedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
108
|
+
if (installedIDEs.length === 0) {
|
|
109
|
+
return {
|
|
110
|
+
status: 'warning',
|
|
111
|
+
message: 'No IDEs detected to validate configs'
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
let validCount = 0;
|
|
115
|
+
let invalidCount = 0;
|
|
116
|
+
const invalid = [];
|
|
117
|
+
for (const ide of installedIDEs) {
|
|
118
|
+
const configPath = (0, ide_detector_1.expandPath)(ide.configPath);
|
|
119
|
+
if (!fs_1.default.existsSync(configPath)) {
|
|
120
|
+
continue; // Skip missing configs
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
if (ide.configFormat === 'json') {
|
|
124
|
+
JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
125
|
+
validCount++;
|
|
126
|
+
}
|
|
127
|
+
else if (ide.configFormat === 'toml') {
|
|
128
|
+
// Basic TOML validation - just check if file is readable
|
|
129
|
+
fs_1.default.readFileSync(configPath, 'utf8');
|
|
130
|
+
validCount++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
invalidCount++;
|
|
135
|
+
invalid.push(`${ide.name}: ${error.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (invalidCount === 0 && validCount > 0) {
|
|
139
|
+
return {
|
|
140
|
+
status: 'passed',
|
|
141
|
+
message: `All ${validCount} MCP config(s) valid`,
|
|
142
|
+
details: { validCount }
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (invalidCount > 0) {
|
|
146
|
+
return {
|
|
147
|
+
status: 'error',
|
|
148
|
+
message: `${invalidCount} invalid MCP config(s)`,
|
|
149
|
+
suggestion: 'Fix syntax errors in MCP configuration files',
|
|
150
|
+
details: { invalid }
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
status: 'warning',
|
|
155
|
+
message: 'No MCP configs to validate'
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Check if FRAIM MCP server is configured in IDEs
|
|
162
|
+
*/
|
|
163
|
+
function checkFraimServerConfigured() {
|
|
164
|
+
return {
|
|
165
|
+
name: 'FRAIM MCP server configured',
|
|
166
|
+
category: 'ideConfiguration',
|
|
167
|
+
critical: false,
|
|
168
|
+
run: async () => {
|
|
169
|
+
const installedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
170
|
+
if (installedIDEs.length === 0) {
|
|
171
|
+
return {
|
|
172
|
+
status: 'warning',
|
|
173
|
+
message: 'No IDEs detected to check FRAIM server'
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
let configuredCount = 0;
|
|
177
|
+
let missingCount = 0;
|
|
178
|
+
const missing = [];
|
|
179
|
+
for (const ide of installedIDEs) {
|
|
180
|
+
const configPath = (0, ide_detector_1.expandPath)(ide.configPath);
|
|
181
|
+
if (!fs_1.default.existsSync(configPath)) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
if (ide.configFormat === 'json') {
|
|
186
|
+
const config = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
|
|
187
|
+
let servers = config.mcpServers || {};
|
|
188
|
+
if (Object.keys(servers).length === 0 && config.servers) {
|
|
189
|
+
servers = config.servers;
|
|
190
|
+
}
|
|
191
|
+
if (servers['fraim']) {
|
|
192
|
+
configuredCount++;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
missingCount++;
|
|
196
|
+
missing.push(ide.name);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (ide.configFormat === 'toml') {
|
|
200
|
+
const toml = require('toml');
|
|
201
|
+
const content = fs_1.default.readFileSync(configPath, 'utf8');
|
|
202
|
+
const config = toml.parse(content);
|
|
203
|
+
const servers = config.mcp_servers || {};
|
|
204
|
+
if (servers['fraim']) {
|
|
205
|
+
configuredCount++;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
missingCount++;
|
|
209
|
+
missing.push(ide.name);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
// Config validation already failed in previous check
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (missingCount === 0 && configuredCount > 0) {
|
|
218
|
+
return {
|
|
219
|
+
status: 'passed',
|
|
220
|
+
message: `FRAIM server configured in all ${configuredCount} IDE(s)`,
|
|
221
|
+
details: { configuredCount }
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
if (missingCount > 0) {
|
|
225
|
+
return {
|
|
226
|
+
status: 'warning',
|
|
227
|
+
message: `FRAIM server missing in ${missingCount} IDE(s): ${missing.join(', ')}`,
|
|
228
|
+
suggestion: 'Run fraim add-ide to configure FRAIM server',
|
|
229
|
+
command: 'fraim add-ide',
|
|
230
|
+
details: { missing, configuredCount, missingCount }
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
status: 'passed',
|
|
235
|
+
message: 'No IDEs with MCP configs to check'
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get all IDE configuration checks
|
|
242
|
+
*/
|
|
243
|
+
function getIDEConfigChecks() {
|
|
244
|
+
return [
|
|
245
|
+
checkIDEsDetected(),
|
|
246
|
+
checkMCPConfigsExist(),
|
|
247
|
+
checkMCPConfigsValid(),
|
|
248
|
+
checkFraimServerConfigured()
|
|
249
|
+
];
|
|
250
|
+
}
|