@tostudy-ai/mcp-setup 1.0.2 → 1.1.0
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 +1 -1
- package/dist/__tests__/e2e-wizard-flow.test.d.ts.map +1 -1
- package/dist/__tests__/e2e-wizard-flow.test.js +128 -117
- package/dist/__tests__/e2e-wizard-flow.test.js.map +1 -1
- package/dist/__tests__/ide-handlers.test.js +15 -11
- package/dist/__tests__/ide-handlers.test.js.map +1 -1
- package/dist/__tests__/install-command.test.js +106 -95
- package/dist/__tests__/install-command.test.js.map +1 -1
- package/dist/config.d.ts +15 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +79 -29
- package/dist/config.js.map +1 -1
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.d.ts.map +1 -1
- package/dist/diagnose.js +154 -164
- package/dist/diagnose.js.map +1 -1
- package/dist/ide-handlers/antigravity.js +1 -1
- package/dist/ide-handlers/antigravity.js.map +1 -1
- package/dist/ide-handlers/base.d.ts +8 -8
- package/dist/ide-handlers/base.d.ts.map +1 -1
- package/dist/ide-handlers/base.js +29 -4
- package/dist/ide-handlers/base.js.map +1 -1
- package/dist/ide-handlers/claude-code.js +1 -1
- package/dist/ide-handlers/claude-code.js.map +1 -1
- package/dist/ide-handlers/codex.js +1 -1
- package/dist/ide-handlers/codex.js.map +1 -1
- package/dist/ide-handlers/cursor.js +1 -1
- package/dist/ide-handlers/cursor.js.map +1 -1
- package/dist/ide-handlers/desktop.d.ts +3 -3
- package/dist/ide-handlers/desktop.d.ts.map +1 -1
- package/dist/ide-handlers/desktop.js +32 -8
- package/dist/ide-handlers/desktop.js.map +1 -1
- package/dist/ide-handlers/manual.js +1 -1
- package/dist/ide-handlers/manual.js.map +1 -1
- package/dist/ide-handlers/opencode.js +1 -1
- package/dist/ide-handlers/opencode.js.map +1 -1
- package/dist/ide-handlers/vscode.js +1 -1
- package/dist/ide-handlers/vscode.js.map +1 -1
- package/dist/ide-handlers/windsurf.js +1 -1
- package/dist/ide-handlers/windsurf.js.map +1 -1
- package/dist/index.js +198 -156
- package/dist/index.js.map +1 -1
- package/dist/repair.d.ts +1 -1
- package/dist/repair.d.ts.map +1 -1
- package/dist/repair.js +213 -168
- package/dist/repair.js.map +1 -1
- package/package.json +5 -5
package/dist/repair.js
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* Provides automatic repair functions for common MCP configuration issues.
|
|
6
6
|
* Works in conjunction with diagnose.ts to fix detected problems.
|
|
7
7
|
*/
|
|
8
|
-
import { existsSync, mkdirSync, writeFileSync, copyFileSync } from
|
|
9
|
-
import { dirname } from
|
|
10
|
-
import chalk from
|
|
11
|
-
import { getClaudeConfigPath, readClaudeConfig, writeClaudeConfig, addTostudyMcpServer, } from
|
|
12
|
-
import { runDiagnostics } from
|
|
13
|
-
const DEFAULT_PLATFORM_URL =
|
|
14
|
-
function println(message =
|
|
8
|
+
import { existsSync, mkdirSync, writeFileSync, copyFileSync } from "node:fs";
|
|
9
|
+
import { dirname } from "node:path";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import { getClaudeConfigPath, readClaudeConfig, writeClaudeConfig, addTostudyMcpServer, extractApiKey, extractMcpUrl, } from "./config.js";
|
|
12
|
+
import { runDiagnostics } from "./diagnose.js";
|
|
13
|
+
const DEFAULT_PLATFORM_URL = "https://tostudy.com";
|
|
14
|
+
function println(message = "") {
|
|
15
15
|
process.stdout.write(`${message}\n`);
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
@@ -29,17 +29,17 @@ function repairMissingConfig() {
|
|
|
29
29
|
const initialConfig = {
|
|
30
30
|
mcpServers: {},
|
|
31
31
|
};
|
|
32
|
-
writeFileSync(configPath, JSON.stringify(initialConfig, null, 2),
|
|
32
|
+
writeFileSync(configPath, JSON.stringify(initialConfig, null, 2), "utf-8");
|
|
33
33
|
return {
|
|
34
|
-
issueId:
|
|
34
|
+
issueId: "config-missing",
|
|
35
35
|
success: true,
|
|
36
|
-
message:
|
|
36
|
+
message: "Arquivo de configuracao criado com sucesso.",
|
|
37
37
|
action: `Criado: ${configPath}`,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
return {
|
|
42
|
-
issueId:
|
|
42
|
+
issueId: "config-missing",
|
|
43
43
|
success: false,
|
|
44
44
|
message: `Falha ao criar arquivo de configuracao: ${error instanceof Error ? error.message : String(error)}`,
|
|
45
45
|
};
|
|
@@ -59,23 +59,23 @@ function repairInvalidJson() {
|
|
|
59
59
|
const freshConfig = {
|
|
60
60
|
mcpServers: {},
|
|
61
61
|
};
|
|
62
|
-
writeFileSync(configPath, JSON.stringify(freshConfig, null, 2),
|
|
62
|
+
writeFileSync(configPath, JSON.stringify(freshConfig, null, 2), "utf-8");
|
|
63
63
|
return {
|
|
64
|
-
issueId:
|
|
64
|
+
issueId: "config-invalid-json",
|
|
65
65
|
success: true,
|
|
66
|
-
message:
|
|
66
|
+
message: "Arquivo de configuracao recriado. Backup salvo.",
|
|
67
67
|
action: `Backup: ${backupPath}`,
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
return {
|
|
71
|
-
issueId:
|
|
71
|
+
issueId: "config-invalid-json",
|
|
72
72
|
success: false,
|
|
73
|
-
message:
|
|
73
|
+
message: "Arquivo de configuracao nao existe.",
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
catch (error) {
|
|
77
77
|
return {
|
|
78
|
-
issueId:
|
|
78
|
+
issueId: "config-invalid-json",
|
|
79
79
|
success: false,
|
|
80
80
|
message: `Falha ao reparar JSON: ${error instanceof Error ? error.message : String(error)}`,
|
|
81
81
|
};
|
|
@@ -88,15 +88,15 @@ function repairMcpNotConfigured(apiKey, platformUrl = DEFAULT_PLATFORM_URL) {
|
|
|
88
88
|
try {
|
|
89
89
|
addTostudyMcpServer(apiKey, platformUrl);
|
|
90
90
|
return {
|
|
91
|
-
issueId:
|
|
91
|
+
issueId: "mcp-not-configured",
|
|
92
92
|
success: true,
|
|
93
|
-
message:
|
|
94
|
-
action:
|
|
93
|
+
message: "Servidor MCP da Catalyst configurado com sucesso.",
|
|
94
|
+
action: "Servidor tostudy adicionado",
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
catch (error) {
|
|
98
98
|
return {
|
|
99
|
-
issueId:
|
|
99
|
+
issueId: "mcp-not-configured",
|
|
100
100
|
success: false,
|
|
101
101
|
message: `Falha ao configurar MCP: ${error instanceof Error ? error.message : String(error)}`,
|
|
102
102
|
};
|
|
@@ -110,92 +110,116 @@ function repairApiKeyMissing(apiKey, platformUrl = DEFAULT_PLATFORM_URL) {
|
|
|
110
110
|
// Re-add the server with the correct API key
|
|
111
111
|
addTostudyMcpServer(apiKey, platformUrl);
|
|
112
112
|
return {
|
|
113
|
-
issueId:
|
|
113
|
+
issueId: "api-key-missing",
|
|
114
114
|
success: true,
|
|
115
|
-
message:
|
|
116
|
-
action:
|
|
115
|
+
message: "API key configurada com sucesso.",
|
|
116
|
+
action: "Header Authorization adicionado",
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
catch (error) {
|
|
120
120
|
return {
|
|
121
|
-
issueId:
|
|
121
|
+
issueId: "api-key-missing",
|
|
122
122
|
success: false,
|
|
123
123
|
message: `Falha ao configurar API key: ${error instanceof Error ? error.message : String(error)}`,
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
|
-
* Fix invalid API key format (
|
|
128
|
+
* Fix invalid API key format (supports both SSE and stdio formats)
|
|
129
129
|
*/
|
|
130
130
|
function repairApiKeyFormat() {
|
|
131
131
|
const config = readClaudeConfig();
|
|
132
|
-
const mcpConfig = config.mcpServers?.[
|
|
132
|
+
const mcpConfig = config.mcpServers?.["tostudy"];
|
|
133
133
|
if (!mcpConfig) {
|
|
134
134
|
return {
|
|
135
|
-
issueId:
|
|
135
|
+
issueId: "api-key-invalid-format",
|
|
136
136
|
success: false,
|
|
137
|
-
message:
|
|
137
|
+
message: "Servidor MCP nao esta configurado.",
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (!
|
|
145
|
-
mcpConfig.headers = {}
|
|
141
|
+
// SSE format: fix headers
|
|
142
|
+
if (mcpConfig.headers) {
|
|
143
|
+
const authHeader = mcpConfig.headers["Authorization"] || "";
|
|
144
|
+
if (authHeader && !authHeader.startsWith("Bearer ")) {
|
|
145
|
+
mcpConfig.headers["Authorization"] = `Bearer ${authHeader}`;
|
|
146
|
+
writeClaudeConfig(config);
|
|
147
|
+
return {
|
|
148
|
+
issueId: "api-key-invalid-format",
|
|
149
|
+
success: true,
|
|
150
|
+
message: "Formato de API key corrigido.",
|
|
151
|
+
action: 'Prefixo "Bearer " adicionado',
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Stdio format: fix args
|
|
156
|
+
if (mcpConfig.args) {
|
|
157
|
+
for (let i = 0; i < mcpConfig.args.length; i++) {
|
|
158
|
+
if (mcpConfig.args[i] === "--header" &&
|
|
159
|
+
mcpConfig.args[i + 1]?.startsWith("Authorization:")) {
|
|
160
|
+
const value = mcpConfig.args[i + 1].replace("Authorization:", "");
|
|
161
|
+
if (value && !value.startsWith("Bearer ")) {
|
|
162
|
+
mcpConfig.args[i + 1] = `Authorization:Bearer ${value}`;
|
|
163
|
+
writeClaudeConfig(config);
|
|
164
|
+
return {
|
|
165
|
+
issueId: "api-key-invalid-format",
|
|
166
|
+
success: true,
|
|
167
|
+
message: "Formato de API key corrigido.",
|
|
168
|
+
action: 'Prefixo "Bearer " adicionado',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
146
172
|
}
|
|
147
|
-
mcpConfig.headers['Authorization'] = `Bearer ${authHeader}`;
|
|
148
|
-
writeClaudeConfig(config);
|
|
149
|
-
return {
|
|
150
|
-
issueId: 'api-key-invalid-format',
|
|
151
|
-
success: true,
|
|
152
|
-
message: 'Formato de API key corrigido.',
|
|
153
|
-
action: 'Prefixo "Bearer " adicionado',
|
|
154
|
-
};
|
|
155
173
|
}
|
|
156
174
|
return {
|
|
157
|
-
issueId:
|
|
175
|
+
issueId: "api-key-invalid-format",
|
|
158
176
|
success: false,
|
|
159
|
-
message:
|
|
177
|
+
message: "API key nao encontrada para corrigir.",
|
|
160
178
|
};
|
|
161
179
|
}
|
|
162
180
|
catch (error) {
|
|
163
181
|
return {
|
|
164
|
-
issueId:
|
|
182
|
+
issueId: "api-key-invalid-format",
|
|
165
183
|
success: false,
|
|
166
184
|
message: `Falha ao corrigir formato: ${error instanceof Error ? error.message : String(error)}`,
|
|
167
185
|
};
|
|
168
186
|
}
|
|
169
187
|
}
|
|
170
188
|
/**
|
|
171
|
-
* Fix missing or invalid server URL
|
|
189
|
+
* Fix missing or invalid server URL by re-adding with correct config
|
|
172
190
|
*/
|
|
173
191
|
function repairServerUrl(platformUrl = DEFAULT_PLATFORM_URL) {
|
|
174
192
|
const config = readClaudeConfig();
|
|
175
|
-
const mcpConfig = config.mcpServers?.[
|
|
193
|
+
const mcpConfig = config.mcpServers?.["tostudy"];
|
|
176
194
|
if (!mcpConfig) {
|
|
177
195
|
return {
|
|
178
|
-
issueId:
|
|
196
|
+
issueId: "server-url-missing",
|
|
179
197
|
success: false,
|
|
180
|
-
message:
|
|
198
|
+
message: "Servidor MCP nao esta configurado.",
|
|
181
199
|
};
|
|
182
200
|
}
|
|
183
201
|
try {
|
|
184
|
-
//
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
202
|
+
// Extract existing API key to preserve it
|
|
203
|
+
const apiKey = extractApiKey(mcpConfig);
|
|
204
|
+
if (!apiKey) {
|
|
205
|
+
return {
|
|
206
|
+
issueId: "server-url-missing",
|
|
207
|
+
success: false,
|
|
208
|
+
message: "API key nao encontrada para reconstruir configuracao.",
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// Re-add with correct URL using stdio format
|
|
212
|
+
addTostudyMcpServer(apiKey, platformUrl);
|
|
189
213
|
return {
|
|
190
|
-
issueId:
|
|
214
|
+
issueId: "server-url-missing",
|
|
191
215
|
success: true,
|
|
192
|
-
message:
|
|
193
|
-
action: `URL: ${
|
|
216
|
+
message: "URL do servidor configurada.",
|
|
217
|
+
action: `URL: ${platformUrl}/mcp`,
|
|
194
218
|
};
|
|
195
219
|
}
|
|
196
220
|
catch (error) {
|
|
197
221
|
return {
|
|
198
|
-
issueId:
|
|
222
|
+
issueId: "server-url-missing",
|
|
199
223
|
success: false,
|
|
200
224
|
message: `Falha ao configurar URL: ${error instanceof Error ? error.message : String(error)}`,
|
|
201
225
|
};
|
|
@@ -206,76 +230,96 @@ function repairServerUrl(platformUrl = DEFAULT_PLATFORM_URL) {
|
|
|
206
230
|
*/
|
|
207
231
|
function repairServerUrlProtocol(platformUrl = DEFAULT_PLATFORM_URL) {
|
|
208
232
|
const config = readClaudeConfig();
|
|
209
|
-
const mcpConfig = config.mcpServers?.[
|
|
210
|
-
if (!mcpConfig
|
|
233
|
+
const mcpConfig = config.mcpServers?.["tostudy"];
|
|
234
|
+
if (!mcpConfig) {
|
|
211
235
|
return {
|
|
212
|
-
issueId:
|
|
236
|
+
issueId: "server-url-invalid-protocol",
|
|
213
237
|
success: false,
|
|
214
|
-
message:
|
|
238
|
+
message: "Servidor MCP nao esta configurado.",
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const url = extractMcpUrl(mcpConfig);
|
|
242
|
+
if (!url) {
|
|
243
|
+
return {
|
|
244
|
+
issueId: "server-url-invalid-protocol",
|
|
245
|
+
success: false,
|
|
246
|
+
message: "URL do servidor nao configurada.",
|
|
215
247
|
};
|
|
216
248
|
}
|
|
217
249
|
try {
|
|
218
|
-
//
|
|
219
|
-
const
|
|
220
|
-
//
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
250
|
+
// Fix the protocol to https and re-add
|
|
251
|
+
const fixedUrl = url.replace(/^[a-z]+:/, "https:");
|
|
252
|
+
// Extract base platform URL from the fixed URL
|
|
253
|
+
const basePlatformUrl = fixedUrl.replace(/\/mcp(\/sse)?$/, "");
|
|
254
|
+
const apiKey = extractApiKey(mcpConfig);
|
|
255
|
+
if (!apiKey) {
|
|
256
|
+
return {
|
|
257
|
+
issueId: "server-url-invalid-protocol",
|
|
258
|
+
success: false,
|
|
259
|
+
message: "API key nao encontrada para reconstruir configuracao.",
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
addTostudyMcpServer(apiKey, basePlatformUrl);
|
|
224
263
|
return {
|
|
225
|
-
issueId:
|
|
264
|
+
issueId: "server-url-invalid-protocol",
|
|
226
265
|
success: true,
|
|
227
|
-
message:
|
|
228
|
-
action: `URL: ${
|
|
266
|
+
message: "Protocolo da URL corrigido para HTTPS.",
|
|
267
|
+
action: `URL: ${basePlatformUrl}/mcp`,
|
|
229
268
|
};
|
|
230
269
|
}
|
|
231
270
|
catch (error) {
|
|
232
271
|
return {
|
|
233
|
-
issueId:
|
|
272
|
+
issueId: "server-url-invalid-protocol",
|
|
234
273
|
success: false,
|
|
235
274
|
message: `Falha ao corrigir protocolo: ${error instanceof Error ? error.message : String(error)}`,
|
|
236
275
|
};
|
|
237
276
|
}
|
|
238
277
|
}
|
|
239
278
|
/**
|
|
240
|
-
* Fix URL missing /mcp
|
|
279
|
+
* Fix URL missing /mcp path
|
|
241
280
|
*/
|
|
242
281
|
function repairServerUrlPath() {
|
|
243
282
|
const config = readClaudeConfig();
|
|
244
|
-
const mcpConfig = config.mcpServers?.[
|
|
245
|
-
if (!mcpConfig
|
|
283
|
+
const mcpConfig = config.mcpServers?.["tostudy"];
|
|
284
|
+
if (!mcpConfig) {
|
|
285
|
+
return {
|
|
286
|
+
issueId: "server-url-missing-sse-path",
|
|
287
|
+
success: false,
|
|
288
|
+
message: "Servidor MCP nao esta configurado.",
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const url = extractMcpUrl(mcpConfig);
|
|
292
|
+
if (!url) {
|
|
246
293
|
return {
|
|
247
|
-
issueId:
|
|
294
|
+
issueId: "server-url-missing-sse-path",
|
|
248
295
|
success: false,
|
|
249
|
-
message:
|
|
296
|
+
message: "URL do servidor nao configurada.",
|
|
250
297
|
};
|
|
251
298
|
}
|
|
252
299
|
try {
|
|
253
|
-
let url = mcpConfig.url;
|
|
254
|
-
// Parse URL and fix path
|
|
255
300
|
const parsedUrl = new URL(url);
|
|
256
|
-
//
|
|
257
|
-
parsedUrl.pathname = parsedUrl.pathname.replace(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
301
|
+
// Extract base URL (strip /mcp or /mcp/sse if present, then re-add /mcp)
|
|
302
|
+
parsedUrl.pathname = parsedUrl.pathname.replace(/\/(mcp(\/sse)?)?$/, "");
|
|
303
|
+
const basePlatformUrl = parsedUrl.toString().replace(/\/$/, "");
|
|
304
|
+
const apiKey = extractApiKey(mcpConfig);
|
|
305
|
+
if (!apiKey) {
|
|
306
|
+
return {
|
|
307
|
+
issueId: "server-url-missing-sse-path",
|
|
308
|
+
success: false,
|
|
309
|
+
message: "API key nao encontrada para reconstruir configuracao.",
|
|
310
|
+
};
|
|
266
311
|
}
|
|
267
|
-
|
|
268
|
-
writeClaudeConfig(config);
|
|
312
|
+
addTostudyMcpServer(apiKey, basePlatformUrl);
|
|
269
313
|
return {
|
|
270
|
-
issueId:
|
|
314
|
+
issueId: "server-url-missing-sse-path",
|
|
271
315
|
success: true,
|
|
272
|
-
message:
|
|
273
|
-
action: `URL: ${
|
|
316
|
+
message: "Path /mcp corrigido na URL.",
|
|
317
|
+
action: `URL: ${basePlatformUrl}/mcp`,
|
|
274
318
|
};
|
|
275
319
|
}
|
|
276
320
|
catch (error) {
|
|
277
321
|
return {
|
|
278
|
-
issueId:
|
|
322
|
+
issueId: "server-url-missing-sse-path",
|
|
279
323
|
success: false,
|
|
280
324
|
message: `Falha ao corrigir path: ${error instanceof Error ? error.message : String(error)}`,
|
|
281
325
|
};
|
|
@@ -288,25 +332,25 @@ function repairDuplicateServers() {
|
|
|
288
332
|
const config = readClaudeConfig();
|
|
289
333
|
if (!config.mcpServers) {
|
|
290
334
|
return {
|
|
291
|
-
issueId:
|
|
335
|
+
issueId: "duplicate-servers",
|
|
292
336
|
success: false,
|
|
293
|
-
message:
|
|
337
|
+
message: "Nenhum servidor MCP configurado.",
|
|
294
338
|
};
|
|
295
339
|
}
|
|
296
340
|
try {
|
|
297
341
|
const servers = Object.entries(config.mcpServers);
|
|
298
|
-
const anaServers = servers.filter(([key, server]) => key.toLowerCase().includes(
|
|
299
|
-
key.toLowerCase().includes(
|
|
300
|
-
(server.url && server.url.includes(
|
|
342
|
+
const anaServers = servers.filter(([key, server]) => key.toLowerCase().includes("ana") ||
|
|
343
|
+
key.toLowerCase().includes("catalyst") ||
|
|
344
|
+
(server.url && server.url.includes("tostudy.com")));
|
|
301
345
|
if (anaServers.length <= 1) {
|
|
302
346
|
return {
|
|
303
|
-
issueId:
|
|
347
|
+
issueId: "duplicate-servers",
|
|
304
348
|
success: true,
|
|
305
|
-
message:
|
|
349
|
+
message: "Nenhuma duplicata encontrada.",
|
|
306
350
|
};
|
|
307
351
|
}
|
|
308
352
|
// Keep the tostudy entry if it exists, otherwise keep the first one
|
|
309
|
-
const primaryKey = anaServers.find(([key]) => key ===
|
|
353
|
+
const primaryKey = anaServers.find(([key]) => key === "tostudy")?.[0] || anaServers[0][0];
|
|
310
354
|
const removedKeys = [];
|
|
311
355
|
for (const [key] of anaServers) {
|
|
312
356
|
if (key !== primaryKey) {
|
|
@@ -316,78 +360,78 @@ function repairDuplicateServers() {
|
|
|
316
360
|
}
|
|
317
361
|
writeClaudeConfig(config);
|
|
318
362
|
return {
|
|
319
|
-
issueId:
|
|
363
|
+
issueId: "duplicate-servers",
|
|
320
364
|
success: true,
|
|
321
365
|
message: `${removedKeys.length} servidor(es) duplicado(s) removido(s).`,
|
|
322
|
-
action: `Removidos: ${removedKeys.join(
|
|
366
|
+
action: `Removidos: ${removedKeys.join(", ")}`,
|
|
323
367
|
};
|
|
324
368
|
}
|
|
325
369
|
catch (error) {
|
|
326
370
|
return {
|
|
327
|
-
issueId:
|
|
371
|
+
issueId: "duplicate-servers",
|
|
328
372
|
success: false,
|
|
329
373
|
message: `Falha ao remover duplicatas: ${error instanceof Error ? error.message : String(error)}`,
|
|
330
374
|
};
|
|
331
375
|
}
|
|
332
376
|
}
|
|
333
377
|
const REPAIR_FUNCTIONS = {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
378
|
+
"config-missing": () => repairMissingConfig(),
|
|
379
|
+
"config-invalid-json": () => repairInvalidJson(),
|
|
380
|
+
"mcp-not-configured": (apiKey, platformUrl) => {
|
|
337
381
|
if (!apiKey) {
|
|
338
382
|
return {
|
|
339
|
-
issueId:
|
|
383
|
+
issueId: "mcp-not-configured",
|
|
340
384
|
success: false,
|
|
341
|
-
message:
|
|
385
|
+
message: "API key necessaria para configurar o MCP.",
|
|
342
386
|
};
|
|
343
387
|
}
|
|
344
388
|
return repairMcpNotConfigured(apiKey, platformUrl);
|
|
345
389
|
},
|
|
346
|
-
|
|
390
|
+
"api-key-missing": (apiKey, platformUrl) => {
|
|
347
391
|
if (!apiKey) {
|
|
348
392
|
return {
|
|
349
|
-
issueId:
|
|
393
|
+
issueId: "api-key-missing",
|
|
350
394
|
success: false,
|
|
351
|
-
message:
|
|
395
|
+
message: "Nova API key necessaria.",
|
|
352
396
|
};
|
|
353
397
|
}
|
|
354
398
|
return repairApiKeyMissing(apiKey, platformUrl);
|
|
355
399
|
},
|
|
356
|
-
|
|
357
|
-
|
|
400
|
+
"api-key-invalid-format": () => repairApiKeyFormat(),
|
|
401
|
+
"api-key-too-short": (apiKey, platformUrl) => {
|
|
358
402
|
if (!apiKey) {
|
|
359
403
|
return {
|
|
360
|
-
issueId:
|
|
404
|
+
issueId: "api-key-too-short",
|
|
361
405
|
success: false,
|
|
362
|
-
message:
|
|
406
|
+
message: "Nova API key necessaria.",
|
|
363
407
|
};
|
|
364
408
|
}
|
|
365
409
|
return repairApiKeyMissing(apiKey, platformUrl);
|
|
366
410
|
},
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
411
|
+
"server-url-missing": (_, platformUrl) => repairServerUrl(platformUrl),
|
|
412
|
+
"server-url-invalid": (_, platformUrl) => repairServerUrl(platformUrl),
|
|
413
|
+
"server-url-invalid-protocol": () => repairServerUrlProtocol(),
|
|
414
|
+
"server-url-missing-sse-path": () => repairServerUrlPath(),
|
|
415
|
+
"auth-failed": (apiKey, platformUrl) => {
|
|
372
416
|
if (!apiKey) {
|
|
373
417
|
return {
|
|
374
|
-
issueId:
|
|
418
|
+
issueId: "auth-failed",
|
|
375
419
|
success: false,
|
|
376
|
-
message:
|
|
420
|
+
message: "Nova API key necessaria. Gere em /student/settings/mcp.",
|
|
377
421
|
};
|
|
378
422
|
}
|
|
379
423
|
return repairMcpNotConfigured(apiKey, platformUrl);
|
|
380
424
|
},
|
|
381
|
-
|
|
425
|
+
"duplicate-servers": () => repairDuplicateServers(),
|
|
382
426
|
};
|
|
383
427
|
/**
|
|
384
428
|
* Issues that require user input (API key)
|
|
385
429
|
*/
|
|
386
430
|
const ISSUES_REQUIRING_API_KEY = [
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
431
|
+
"mcp-not-configured",
|
|
432
|
+
"api-key-missing",
|
|
433
|
+
"api-key-too-short",
|
|
434
|
+
"auth-failed",
|
|
391
435
|
];
|
|
392
436
|
/**
|
|
393
437
|
* Check if an issue requires user input to repair
|
|
@@ -426,7 +470,7 @@ export function repairAllIssues(report, apiKey, platformUrl = DEFAULT_PLATFORM_U
|
|
|
426
470
|
results.push({
|
|
427
471
|
issueId: issue.id,
|
|
428
472
|
success: false,
|
|
429
|
-
message:
|
|
473
|
+
message: "Requer API key para reparar.",
|
|
430
474
|
});
|
|
431
475
|
failed++;
|
|
432
476
|
continue;
|
|
@@ -462,63 +506,63 @@ export async function diagnoseAndRepair(apiKey, platformUrl = DEFAULT_PLATFORM_U
|
|
|
462
506
|
*/
|
|
463
507
|
export function printRepairReport(report) {
|
|
464
508
|
println();
|
|
465
|
-
println(chalk.cyan(
|
|
466
|
-
println(chalk.cyan(
|
|
467
|
-
println(chalk.cyan(
|
|
509
|
+
println(chalk.cyan(" ╔═══════════════════════════════════════╗"));
|
|
510
|
+
println(chalk.cyan(" ║") + chalk.white.bold(" Catalyst MCP Auto-Repair ") + chalk.cyan("║"));
|
|
511
|
+
println(chalk.cyan(" ╚═══════════════════════════════════════╝"));
|
|
468
512
|
println();
|
|
469
513
|
if (report.repairsAttempted === 0) {
|
|
470
|
-
println(chalk.green.bold(
|
|
514
|
+
println(chalk.green.bold("✓ Nenhum reparo necessario!"));
|
|
471
515
|
println();
|
|
472
|
-
println(chalk.gray(
|
|
516
|
+
println(chalk.gray("Nenhum problema corrigivel automaticamente foi encontrado."));
|
|
473
517
|
println();
|
|
474
518
|
return;
|
|
475
519
|
}
|
|
476
520
|
// Summary
|
|
477
|
-
println(chalk.white.bold(
|
|
521
|
+
println(chalk.white.bold("Resumo:"));
|
|
478
522
|
println(` Reparos tentados: ${report.repairsAttempted}`);
|
|
479
|
-
println(` ${chalk.green(
|
|
523
|
+
println(` ${chalk.green("✓ Sucesso:")} ${report.repairsSucceeded}`);
|
|
480
524
|
if (report.repairsFailed > 0) {
|
|
481
|
-
println(` ${chalk.red(
|
|
525
|
+
println(` ${chalk.red("✗ Falha:")} ${report.repairsFailed}`);
|
|
482
526
|
}
|
|
483
527
|
println();
|
|
484
528
|
// Results
|
|
485
|
-
println(chalk.white.bold(
|
|
529
|
+
println(chalk.white.bold("Detalhes:"));
|
|
486
530
|
println();
|
|
487
531
|
for (const result of report.results) {
|
|
488
532
|
if (result.success) {
|
|
489
|
-
println(` ${chalk.green(
|
|
533
|
+
println(` ${chalk.green("✓")} ${result.message}`);
|
|
490
534
|
if (result.action) {
|
|
491
535
|
println(chalk.gray(` ${result.action}`));
|
|
492
536
|
}
|
|
493
537
|
}
|
|
494
538
|
else {
|
|
495
|
-
println(` ${chalk.red(
|
|
539
|
+
println(` ${chalk.red("✗")} ${result.message}`);
|
|
496
540
|
}
|
|
497
541
|
}
|
|
498
542
|
println();
|
|
499
543
|
// User input required
|
|
500
544
|
if (report.requiresUserInput.length > 0) {
|
|
501
|
-
println(chalk.yellow(
|
|
545
|
+
println(chalk.yellow("⚠ Alguns reparos requerem interacao:"));
|
|
502
546
|
println();
|
|
503
|
-
println(
|
|
504
|
-
println(chalk.cyan(
|
|
547
|
+
println(" Para reparar problemas de API key, execute:");
|
|
548
|
+
println(chalk.cyan(" npx @tostudy-ai/mcp-setup repair --api-key <sua-api-key>"));
|
|
505
549
|
println();
|
|
506
|
-
println(
|
|
507
|
-
println(chalk.cyan(
|
|
550
|
+
println(" Para gerar uma nova API key:");
|
|
551
|
+
println(chalk.cyan(" https://tostudy.com/student/settings/mcp"));
|
|
508
552
|
println();
|
|
509
553
|
}
|
|
510
554
|
// Final status
|
|
511
555
|
if (report.repairsFailed === 0 && report.requiresUserInput.length === 0) {
|
|
512
|
-
println(chalk.green.bold(
|
|
513
|
-
println(chalk.gray(
|
|
556
|
+
println(chalk.green.bold("✓ Todos os reparos concluidos com sucesso!"));
|
|
557
|
+
println(chalk.gray(" Reinicie o Claude Code para aplicar as mudancas."));
|
|
514
558
|
}
|
|
515
559
|
else if (report.repairsSucceeded > 0) {
|
|
516
|
-
println(chalk.yellow(
|
|
517
|
-
println(chalk.gray(
|
|
560
|
+
println(chalk.yellow("⚠ Alguns reparos foram concluidos, mas outros falharam."));
|
|
561
|
+
println(chalk.gray(" Execute o diagnostico novamente para verificar o status."));
|
|
518
562
|
}
|
|
519
563
|
else {
|
|
520
|
-
println(chalk.red(
|
|
521
|
-
println(chalk.gray(
|
|
564
|
+
println(chalk.red("✗ Nenhum reparo foi concluido com sucesso."));
|
|
565
|
+
println(chalk.gray(" Verifique os erros acima e tente novamente."));
|
|
522
566
|
}
|
|
523
567
|
println();
|
|
524
568
|
}
|
|
@@ -529,7 +573,7 @@ export function exportRepairReportJson(report) {
|
|
|
529
573
|
return JSON.stringify(report, null, 2);
|
|
530
574
|
}
|
|
531
575
|
// CLI entry point
|
|
532
|
-
if (process.argv[1]?.endsWith(
|
|
576
|
+
if (process.argv[1]?.endsWith("repair.js")) {
|
|
533
577
|
(async () => {
|
|
534
578
|
try {
|
|
535
579
|
// Parse command line arguments
|
|
@@ -538,25 +582,25 @@ if (process.argv[1]?.endsWith('repair.js')) {
|
|
|
538
582
|
let jsonOutput = false;
|
|
539
583
|
for (let i = 2; i < process.argv.length; i++) {
|
|
540
584
|
const arg = process.argv[i];
|
|
541
|
-
if (arg ===
|
|
585
|
+
if (arg === "--api-key" && process.argv[i + 1]) {
|
|
542
586
|
apiKey = process.argv[++i];
|
|
543
587
|
}
|
|
544
|
-
else if (arg ===
|
|
588
|
+
else if (arg === "--url" && process.argv[i + 1]) {
|
|
545
589
|
platformUrl = process.argv[++i];
|
|
546
590
|
}
|
|
547
|
-
else if (arg ===
|
|
591
|
+
else if (arg === "--json") {
|
|
548
592
|
jsonOutput = true;
|
|
549
593
|
}
|
|
550
|
-
else if (arg ===
|
|
551
|
-
println(
|
|
594
|
+
else if (arg === "--help" || arg === "-h") {
|
|
595
|
+
println("Catalyst MCP Auto-Repair");
|
|
552
596
|
println();
|
|
553
|
-
println(
|
|
597
|
+
println("Usage: node repair.js [options]");
|
|
554
598
|
println();
|
|
555
|
-
println(
|
|
556
|
-
println(
|
|
557
|
-
println(
|
|
558
|
-
println(
|
|
559
|
-
println(
|
|
599
|
+
println("Options:");
|
|
600
|
+
println(" --api-key <key> API key para reparos que necessitam autenticacao");
|
|
601
|
+
println(" --url <url> URL da plataforma (default: https://tostudy.com)");
|
|
602
|
+
println(" --json Saida em formato JSON");
|
|
603
|
+
println(" --help, -h Mostra esta ajuda");
|
|
560
604
|
println();
|
|
561
605
|
process.exit(0);
|
|
562
606
|
}
|
|
@@ -575,12 +619,13 @@ if (process.argv[1]?.endsWith('repair.js')) {
|
|
|
575
619
|
printRepairReport(repair);
|
|
576
620
|
}
|
|
577
621
|
// Exit code based on repair results
|
|
578
|
-
const hasUnfixedCritical = diagnostic.issues.some((issue) => issue.severity ===
|
|
622
|
+
const hasUnfixedCritical = diagnostic.issues.some((issue) => issue.severity === "critical" &&
|
|
623
|
+
!repair.results.find((r) => r.issueId === issue.id && r.success));
|
|
579
624
|
process.exit(hasUnfixedCritical ? 1 : 0);
|
|
580
625
|
}
|
|
581
626
|
catch (error) {
|
|
582
|
-
process.stderr.write(chalk.red(
|
|
583
|
-
process.stderr.write((error instanceof Error ? error.message : String(error)) +
|
|
627
|
+
process.stderr.write(chalk.red("Erro ao executar reparo:\n"));
|
|
628
|
+
process.stderr.write((error instanceof Error ? error.message : String(error)) + "\n");
|
|
584
629
|
process.exit(1);
|
|
585
630
|
}
|
|
586
631
|
})();
|