@tostudy-ai/mcp-setup 1.0.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 +149 -0
- package/bin/cli.js +6 -0
- package/dist/__tests__/e2e-diagnostic-repair-flow.test.d.ts +52 -0
- package/dist/__tests__/e2e-diagnostic-repair-flow.test.d.ts.map +1 -0
- package/dist/__tests__/e2e-diagnostic-repair-flow.test.js +720 -0
- package/dist/__tests__/e2e-diagnostic-repair-flow.test.js.map +1 -0
- package/dist/__tests__/e2e-wizard-flow.test.d.ts +43 -0
- package/dist/__tests__/e2e-wizard-flow.test.d.ts.map +1 -0
- package/dist/__tests__/e2e-wizard-flow.test.js +407 -0
- package/dist/__tests__/e2e-wizard-flow.test.js.map +1 -0
- package/dist/__tests__/ide-handlers.test.d.ts +10 -0
- package/dist/__tests__/ide-handlers.test.d.ts.map +1 -0
- package/dist/__tests__/ide-handlers.test.js +336 -0
- package/dist/__tests__/ide-handlers.test.js.map +1 -0
- package/dist/__tests__/install-command.test.d.ts +10 -0
- package/dist/__tests__/install-command.test.d.ts.map +1 -0
- package/dist/__tests__/install-command.test.js +237 -0
- package/dist/__tests__/install-command.test.js.map +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +117 -0
- package/dist/config.js.map +1 -0
- package/dist/detect.d.ts +42 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +277 -0
- package/dist/detect.js.map +1 -0
- package/dist/diagnose.d.ts +36 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +512 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/ide-handlers/base.d.ts +36 -0
- package/dist/ide-handlers/base.d.ts.map +1 -0
- package/dist/ide-handlers/base.js +41 -0
- package/dist/ide-handlers/base.js.map +1 -0
- package/dist/ide-handlers/claude-code.d.ts +15 -0
- package/dist/ide-handlers/claude-code.d.ts.map +1 -0
- package/dist/ide-handlers/claude-code.js +50 -0
- package/dist/ide-handlers/claude-code.js.map +1 -0
- package/dist/ide-handlers/cursor.d.ts +15 -0
- package/dist/ide-handlers/cursor.d.ts.map +1 -0
- package/dist/ide-handlers/cursor.js +61 -0
- package/dist/ide-handlers/cursor.js.map +1 -0
- package/dist/ide-handlers/desktop.d.ts +16 -0
- package/dist/ide-handlers/desktop.d.ts.map +1 -0
- package/dist/ide-handlers/desktop.js +26 -0
- package/dist/ide-handlers/desktop.js.map +1 -0
- package/dist/ide-handlers/index.d.ts +21 -0
- package/dist/ide-handlers/index.d.ts.map +1 -0
- package/dist/ide-handlers/index.js +49 -0
- package/dist/ide-handlers/index.js.map +1 -0
- package/dist/ide-handlers/manual.d.ts +16 -0
- package/dist/ide-handlers/manual.d.ts.map +1 -0
- package/dist/ide-handlers/manual.js +34 -0
- package/dist/ide-handlers/manual.js.map +1 -0
- package/dist/ide-handlers/opencode.d.ts +15 -0
- package/dist/ide-handlers/opencode.d.ts.map +1 -0
- package/dist/ide-handlers/opencode.js +57 -0
- package/dist/ide-handlers/opencode.js.map +1 -0
- package/dist/ide-handlers/vscode.d.ts +16 -0
- package/dist/ide-handlers/vscode.d.ts.map +1 -0
- package/dist/ide-handlers/vscode.js +62 -0
- package/dist/ide-handlers/vscode.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +501 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +23 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +68 -0
- package/dist/prompts.js.map +1 -0
- package/dist/repair.d.ts +50 -0
- package/dist/repair.d.ts.map +1 -0
- package/dist/repair.js +588 -0
- package/dist/repair.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Uses `claude mcp add` CLI command to register the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from 'node:child_process';
|
|
7
|
+
import { buildMcpRemoteArgs, verifyHeartbeat } from './base.js';
|
|
8
|
+
export class ClaudeCodeHandler {
|
|
9
|
+
id = 'claude-code';
|
|
10
|
+
name = 'Claude Code';
|
|
11
|
+
async detect() {
|
|
12
|
+
try {
|
|
13
|
+
execFileSync('which', ['claude'], { stdio: 'ignore' });
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
try {
|
|
18
|
+
execFileSync('where', ['claude'], { stdio: 'ignore' });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
getConfigPath() {
|
|
27
|
+
return 'Terminal (claude mcp add)';
|
|
28
|
+
}
|
|
29
|
+
async writeConfig(apiKey, mcpUrl) {
|
|
30
|
+
const args = buildMcpRemoteArgs(apiKey, mcpUrl);
|
|
31
|
+
try {
|
|
32
|
+
// First try to remove existing entry (ignore errors if it doesn't exist)
|
|
33
|
+
try {
|
|
34
|
+
execFileSync('claude', ['mcp', 'remove', 'tostudy'], { stdio: 'ignore' });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Ignore - entry may not exist
|
|
38
|
+
}
|
|
39
|
+
execFileSync('claude', ['mcp', 'add', 'tostudy', '--', 'npx', ...args], { stdio: 'inherit' });
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new Error(`Failed to run 'claude mcp add'. Is Claude Code installed?\n` +
|
|
43
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async verify(apiKey, mcpUrl) {
|
|
47
|
+
return verifyHeartbeat(apiKey, mcpUrl);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/ide-handlers/claude-code.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAmB,kBAAkB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjF,MAAM,OAAO,iBAAiB;IAC5B,EAAE,GAAG,aAAa,CAAC;IACnB,IAAI,GAAG,aAAa,CAAC;IAErB,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,YAAY,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,YAAY,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACvD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAc;QAC9C,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEhD,IAAI,CAAC;YACH,yEAAyE;YACzE,IAAI,CAAC;gBACH,YAAY,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC5E,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;YAED,YAAY,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAChG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,6DAA6D;gBAC7D,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAc;QACzC,OAAO,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Writes to ~/.cursor/mcp.json with { mcpServers: { tostudy: ... } }
|
|
5
|
+
*/
|
|
6
|
+
import { type IDEHandler } from './base.js';
|
|
7
|
+
export declare class CursorHandler implements IDEHandler {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
detect(): Promise<boolean>;
|
|
11
|
+
getConfigPath(): string;
|
|
12
|
+
writeConfig(apiKey: string, mcpUrl: string): Promise<void>;
|
|
13
|
+
verify(apiKey: string, mcpUrl: string): Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/ide-handlers/cursor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,KAAK,UAAU,EAA4C,MAAM,WAAW,CAAC;AAEtF,qBAAa,aAAc,YAAW,UAAU;IAC9C,EAAE,SAAY;IACd,IAAI,SAAY;IAEV,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAmBhC,aAAa,IAAI,MAAM;IAKjB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B1D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAG/D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Writes to ~/.cursor/mcp.json with { mcpServers: { tostudy: ... } }
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
7
|
+
import { join, dirname } from 'node:path';
|
|
8
|
+
import { homedir, platform } from 'node:os';
|
|
9
|
+
import { buildTostudyServerEntry, verifyHeartbeat } from './base.js';
|
|
10
|
+
export class CursorHandler {
|
|
11
|
+
id = 'cursor';
|
|
12
|
+
name = 'Cursor';
|
|
13
|
+
async detect() {
|
|
14
|
+
const home = homedir();
|
|
15
|
+
const os = platform();
|
|
16
|
+
switch (os) {
|
|
17
|
+
case 'darwin':
|
|
18
|
+
return existsSync(join('/Applications', 'Cursor.app')) ||
|
|
19
|
+
existsSync(join(home, 'Applications', 'Cursor.app'));
|
|
20
|
+
case 'win32': {
|
|
21
|
+
const localAppData = process.env.LOCALAPPDATA || join(home, 'AppData', 'Local');
|
|
22
|
+
return existsSync(join(localAppData, 'Programs', 'cursor', 'Cursor.exe'));
|
|
23
|
+
}
|
|
24
|
+
case 'linux':
|
|
25
|
+
return existsSync(join(home, '.cursor'));
|
|
26
|
+
default:
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
getConfigPath() {
|
|
31
|
+
const home = homedir();
|
|
32
|
+
return join(home, '.cursor', 'mcp.json');
|
|
33
|
+
}
|
|
34
|
+
async writeConfig(apiKey, mcpUrl) {
|
|
35
|
+
const configPath = this.getConfigPath();
|
|
36
|
+
const configDir = dirname(configPath);
|
|
37
|
+
// Ensure directory exists
|
|
38
|
+
if (!existsSync(configDir)) {
|
|
39
|
+
mkdirSync(configDir, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
// Read existing config to preserve other servers
|
|
42
|
+
let config = {};
|
|
43
|
+
if (existsSync(configPath)) {
|
|
44
|
+
try {
|
|
45
|
+
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Start fresh if config is corrupted
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Merge - only update tostudy entry
|
|
52
|
+
const mcpServers = config.mcpServers ?? {};
|
|
53
|
+
mcpServers['tostudy'] = buildTostudyServerEntry(apiKey, mcpUrl);
|
|
54
|
+
config.mcpServers = mcpServers;
|
|
55
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
56
|
+
}
|
|
57
|
+
async verify(apiKey, mcpUrl) {
|
|
58
|
+
return verifyHeartbeat(apiKey, mcpUrl);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/ide-handlers/cursor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAmB,uBAAuB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEtF,MAAM,OAAO,aAAa;IACxB,EAAE,GAAG,QAAQ,CAAC;IACd,IAAI,GAAG,QAAQ,CAAC;IAEhB,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;QAEtB,QAAQ,EAAE,EAAE,CAAC;YACX,KAAK,QAAQ;gBACX,OAAO,UAAU,CAAC,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;oBACpD,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;YACzD,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;gBAChF,OAAO,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;YAC5E,CAAC;YACD,KAAK,OAAO;gBACV,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;YAC3C;gBACE,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;IAED,aAAa;QACX,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAc;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QAEtC,0BAA0B;QAC1B,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,iDAAiD;QACjD,IAAI,MAAM,GAA4B,EAAE,CAAC;QACzC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,MAAM,UAAU,GAAI,MAAM,CAAC,UAAsC,IAAI,EAAE,CAAC;QACxE,UAAU,CAAC,SAAS,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChE,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QAE/B,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAc;QACzC,OAAO,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Desktop IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Reuses existing addTostudyMcpServer() from config.ts which writes
|
|
5
|
+
* to ~/Library/Application Support/Claude/claude_desktop_config.json
|
|
6
|
+
*/
|
|
7
|
+
import { type IDEHandler } from './base.js';
|
|
8
|
+
export declare class DesktopHandler implements IDEHandler {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
detect(): Promise<boolean>;
|
|
12
|
+
getConfigPath(): string;
|
|
13
|
+
writeConfig(apiKey: string, mcpUrl: string): Promise<void>;
|
|
14
|
+
verify(apiKey: string, mcpUrl: string): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=desktop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.d.ts","sourceRoot":"","sources":["../../src/ide-handlers/desktop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,WAAW,CAAC;AAO7D,qBAAa,cAAe,YAAW,UAAU;IAC/C,EAAE,SAAa;IACf,IAAI,SAAoB;IAElB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAIhC,aAAa,IAAI,MAAM;IAIjB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAG/D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Desktop IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Reuses existing addTostudyMcpServer() from config.ts which writes
|
|
5
|
+
* to ~/Library/Application Support/Claude/claude_desktop_config.json
|
|
6
|
+
*/
|
|
7
|
+
import { verifyHeartbeat } from './base.js';
|
|
8
|
+
import { isClaudeInstalled, getClaudeConfigPath, addTostudyMcpServer, } from '../config.js';
|
|
9
|
+
export class DesktopHandler {
|
|
10
|
+
id = 'desktop';
|
|
11
|
+
name = 'Claude Desktop';
|
|
12
|
+
async detect() {
|
|
13
|
+
return isClaudeInstalled();
|
|
14
|
+
}
|
|
15
|
+
getConfigPath() {
|
|
16
|
+
return getClaudeConfigPath();
|
|
17
|
+
}
|
|
18
|
+
async writeConfig(apiKey, mcpUrl) {
|
|
19
|
+
// Reuse existing config writer - it handles read-then-merge
|
|
20
|
+
addTostudyMcpServer(apiKey, mcpUrl);
|
|
21
|
+
}
|
|
22
|
+
async verify(apiKey, mcpUrl) {
|
|
23
|
+
return verifyHeartbeat(apiKey, mcpUrl);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.js","sourceRoot":"","sources":["../../src/ide-handlers/desktop.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAmB,eAAe,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,MAAM,OAAO,cAAc;IACzB,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,gBAAgB,CAAC;IAExB,KAAK,CAAC,MAAM;QACV,OAAO,iBAAiB,EAAE,CAAC;IAC7B,CAAC;IAED,aAAa;QACX,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAc;QAC9C,4DAA4D;QAC5D,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAc;QACzC,OAAO,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Handler Factory
|
|
3
|
+
*
|
|
4
|
+
* Registry of all supported IDE handlers.
|
|
5
|
+
*/
|
|
6
|
+
import { type IDEHandler } from './base.js';
|
|
7
|
+
export type SupportedIDE = 'claude-code' | 'cursor' | 'vscode' | 'desktop' | 'opencode' | 'manual';
|
|
8
|
+
/**
|
|
9
|
+
* Get an IDE handler by type.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getIDEHandler(ide: SupportedIDE): IDEHandler;
|
|
12
|
+
/**
|
|
13
|
+
* Get all available IDE handlers.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAllIDEHandlers(): IDEHandler[];
|
|
16
|
+
/**
|
|
17
|
+
* Detect which IDEs are installed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectInstalledIDEs(): Promise<IDEHandler[]>;
|
|
20
|
+
export { type IDEHandler } from './base.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ide-handlers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAQ5C,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAWnG;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,UAAU,CAM3D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,EAAE,CAEhD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAWjE;AAED,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDE Handler Factory
|
|
3
|
+
*
|
|
4
|
+
* Registry of all supported IDE handlers.
|
|
5
|
+
*/
|
|
6
|
+
import { ClaudeCodeHandler } from './claude-code.js';
|
|
7
|
+
import { CursorHandler } from './cursor.js';
|
|
8
|
+
import { VSCodeHandler } from './vscode.js';
|
|
9
|
+
import { DesktopHandler } from './desktop.js';
|
|
10
|
+
import { OpenCodeHandler } from './opencode.js';
|
|
11
|
+
import { ManualHandler } from './manual.js';
|
|
12
|
+
const handlers = {
|
|
13
|
+
'claude-code': () => new ClaudeCodeHandler(),
|
|
14
|
+
'cursor': () => new CursorHandler(),
|
|
15
|
+
'vscode': () => new VSCodeHandler(),
|
|
16
|
+
'desktop': () => new DesktopHandler(),
|
|
17
|
+
'opencode': () => new OpenCodeHandler(),
|
|
18
|
+
'manual': () => new ManualHandler(),
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Get an IDE handler by type.
|
|
22
|
+
*/
|
|
23
|
+
export function getIDEHandler(ide) {
|
|
24
|
+
const factory = handlers[ide];
|
|
25
|
+
if (!factory) {
|
|
26
|
+
throw new Error(`Unknown IDE: ${ide}. Supported: ${Object.keys(handlers).join(', ')}`);
|
|
27
|
+
}
|
|
28
|
+
return factory();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get all available IDE handlers.
|
|
32
|
+
*/
|
|
33
|
+
export function getAllIDEHandlers() {
|
|
34
|
+
return Object.values(handlers).map((factory) => factory());
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Detect which IDEs are installed.
|
|
38
|
+
*/
|
|
39
|
+
export async function detectInstalledIDEs() {
|
|
40
|
+
const all = getAllIDEHandlers();
|
|
41
|
+
const results = [];
|
|
42
|
+
for (const handler of all) {
|
|
43
|
+
if (await handler.detect()) {
|
|
44
|
+
results.push(handler);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ide-handlers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,MAAM,QAAQ,GAA2C;IACvD,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAE;IAC5C,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE;IACnC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE;IACnC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,cAAc,EAAE;IACrC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,eAAe,EAAE;IACvC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAiB;IAC7C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,OAAO,GAAiB,EAAE,CAAC;IAEjC,KAAK,MAAM,OAAO,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual Handler
|
|
3
|
+
*
|
|
4
|
+
* Prints the config to stdout for the user to copy-paste.
|
|
5
|
+
* Does not write to any file.
|
|
6
|
+
*/
|
|
7
|
+
import { type IDEHandler } from './base.js';
|
|
8
|
+
export declare class ManualHandler implements IDEHandler {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
detect(): Promise<boolean>;
|
|
12
|
+
getConfigPath(): string;
|
|
13
|
+
writeConfig(apiKey: string, mcpUrl: string): Promise<void>;
|
|
14
|
+
verify(apiKey: string, mcpUrl: string): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=manual.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../src/ide-handlers/manual.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,KAAK,UAAU,EAA4C,MAAM,WAAW,CAAC;AAEtF,qBAAa,aAAc,YAAW,UAAU;IAC9C,EAAE,SAAY;IACd,IAAI,SAAY;IAEV,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAIhC,aAAa,IAAI,MAAM;IAIjB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAG/D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual Handler
|
|
3
|
+
*
|
|
4
|
+
* Prints the config to stdout for the user to copy-paste.
|
|
5
|
+
* Does not write to any file.
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { buildTostudyServerEntry, verifyHeartbeat } from './base.js';
|
|
9
|
+
export class ManualHandler {
|
|
10
|
+
id = 'manual';
|
|
11
|
+
name = 'Manual';
|
|
12
|
+
async detect() {
|
|
13
|
+
return true; // Always available
|
|
14
|
+
}
|
|
15
|
+
getConfigPath() {
|
|
16
|
+
return 'stdout';
|
|
17
|
+
}
|
|
18
|
+
async writeConfig(apiKey, mcpUrl) {
|
|
19
|
+
const config = {
|
|
20
|
+
mcpServers: {
|
|
21
|
+
tostudy: buildTostudyServerEntry(apiKey, mcpUrl),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
process.stdout.write('\n');
|
|
25
|
+
process.stdout.write(chalk.cyan('Add the following to your MCP config:\n'));
|
|
26
|
+
process.stdout.write('\n');
|
|
27
|
+
process.stdout.write(JSON.stringify(config, null, 2));
|
|
28
|
+
process.stdout.write('\n\n');
|
|
29
|
+
}
|
|
30
|
+
async verify(apiKey, mcpUrl) {
|
|
31
|
+
return verifyHeartbeat(apiKey, mcpUrl);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=manual.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.js","sourceRoot":"","sources":["../../src/ide-handlers/manual.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAmB,uBAAuB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEtF,MAAM,OAAO,aAAa;IACxB,EAAE,GAAG,QAAQ,CAAC;IACd,IAAI,GAAG,QAAQ,CAAC;IAEhB,KAAK,CAAC,MAAM;QACV,OAAO,IAAI,CAAC,CAAC,mBAAmB;IAClC,CAAC;IAED,aAAa;QACX,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAc;QAC9C,MAAM,MAAM,GAAG;YACb,UAAU,EAAE;gBACV,OAAO,EAAE,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC;aACjD;SACF,CAAC;QAEF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAc;QACzC,OAAO,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Writes to ~/.opencode/opencode.json with { mcp: { tostudy: ... } }
|
|
5
|
+
*/
|
|
6
|
+
import { type IDEHandler } from './base.js';
|
|
7
|
+
export declare class OpenCodeHandler implements IDEHandler {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
detect(): Promise<boolean>;
|
|
11
|
+
getConfigPath(): string;
|
|
12
|
+
writeConfig(apiKey: string, mcpUrl: string): Promise<void>;
|
|
13
|
+
verify(apiKey: string, mcpUrl: string): Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=opencode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/ide-handlers/opencode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,KAAK,UAAU,EAA4C,MAAM,WAAW,CAAC;AAEtF,qBAAa,eAAgB,YAAW,UAAU;IAChD,EAAE,SAAc;IAChB,IAAI,SAAc;IAEZ,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAchC,aAAa,IAAI,MAAM;IAIjB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB1D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAG/D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Writes to ~/.opencode/opencode.json with { mcp: { tostudy: ... } }
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
7
|
+
import { execFileSync } from 'node:child_process';
|
|
8
|
+
import { join, dirname } from 'node:path';
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import { buildTostudyServerEntry, verifyHeartbeat } from './base.js';
|
|
11
|
+
export class OpenCodeHandler {
|
|
12
|
+
id = 'opencode';
|
|
13
|
+
name = 'OpenCode';
|
|
14
|
+
async detect() {
|
|
15
|
+
try {
|
|
16
|
+
execFileSync('which', ['opencode'], { stdio: 'ignore' });
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
try {
|
|
21
|
+
execFileSync('where', ['opencode'], { stdio: 'ignore' });
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return existsSync(join(homedir(), '.opencode'));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
getConfigPath() {
|
|
30
|
+
return join(homedir(), '.opencode', 'opencode.json');
|
|
31
|
+
}
|
|
32
|
+
async writeConfig(apiKey, mcpUrl) {
|
|
33
|
+
const configPath = this.getConfigPath();
|
|
34
|
+
const configDir = dirname(configPath);
|
|
35
|
+
if (!existsSync(configDir)) {
|
|
36
|
+
mkdirSync(configDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
let config = {};
|
|
39
|
+
if (existsSync(configPath)) {
|
|
40
|
+
try {
|
|
41
|
+
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Start fresh
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// OpenCode uses "mcp" key
|
|
48
|
+
const mcp = config.mcp ?? {};
|
|
49
|
+
mcp['tostudy'] = buildTostudyServerEntry(apiKey, mcpUrl);
|
|
50
|
+
config.mcp = mcp;
|
|
51
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
async verify(apiKey, mcpUrl) {
|
|
54
|
+
return verifyHeartbeat(apiKey, mcpUrl);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/ide-handlers/opencode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAmB,uBAAuB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEtF,MAAM,OAAO,eAAe;IAC1B,EAAE,GAAG,UAAU,CAAC;IAChB,IAAI,GAAG,UAAU,CAAC;IAElB,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,YAAY,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,YAAY,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACzD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAc;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QAEtC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,MAAM,GAA4B,EAAE,CAAC;QACzC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,cAAc;YAChB,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,MAAM,GAAG,GAAI,MAAM,CAAC,GAA+B,IAAI,EAAE,CAAC;QAC1D,GAAG,CAAC,SAAS,CAAC,GAAG,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;QAEjB,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,MAAc;QACzC,OAAO,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Writes to .vscode/mcp.json with { servers: { tostudy: ... } }
|
|
5
|
+
* Note: VS Code uses "servers" (not "mcpServers") in its config format.
|
|
6
|
+
*/
|
|
7
|
+
import { type IDEHandler } from './base.js';
|
|
8
|
+
export declare class VSCodeHandler implements IDEHandler {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
detect(): Promise<boolean>;
|
|
12
|
+
getConfigPath(): string;
|
|
13
|
+
writeConfig(apiKey: string, mcpUrl: string): Promise<void>;
|
|
14
|
+
verify(apiKey: string, mcpUrl: string): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=vscode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.d.ts","sourceRoot":"","sources":["../../src/ide-handlers/vscode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,KAAK,UAAU,EAA4C,MAAM,WAAW,CAAC;AAEtF,qBAAa,aAAc,YAAW,UAAU;IAC9C,EAAE,SAAY;IACd,IAAI,SAAa;IAEX,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBhC,aAAa,IAAI,MAAM;IAKjB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB1D,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAG/D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code IDE Handler
|
|
3
|
+
*
|
|
4
|
+
* Writes to .vscode/mcp.json with { servers: { tostudy: ... } }
|
|
5
|
+
* Note: VS Code uses "servers" (not "mcpServers") in its config format.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { join, dirname } from 'node:path';
|
|
9
|
+
import { homedir, platform } from 'node:os';
|
|
10
|
+
import { buildTostudyServerEntry, verifyHeartbeat } from './base.js';
|
|
11
|
+
export class VSCodeHandler {
|
|
12
|
+
id = 'vscode';
|
|
13
|
+
name = 'VS Code';
|
|
14
|
+
async detect() {
|
|
15
|
+
const home = homedir();
|
|
16
|
+
const os = platform();
|
|
17
|
+
switch (os) {
|
|
18
|
+
case 'darwin':
|
|
19
|
+
return existsSync(join('/Applications', 'Visual Studio Code.app')) ||
|
|
20
|
+
existsSync(join(home, 'Applications', 'Visual Studio Code.app'));
|
|
21
|
+
case 'win32': {
|
|
22
|
+
const programFiles = process.env.ProgramFiles || 'C:\\Program Files';
|
|
23
|
+
const localAppData = process.env.LOCALAPPDATA || join(home, 'AppData', 'Local');
|
|
24
|
+
return existsSync(join(programFiles, 'Microsoft VS Code', 'Code.exe')) ||
|
|
25
|
+
existsSync(join(localAppData, 'Programs', 'Microsoft VS Code', 'Code.exe'));
|
|
26
|
+
}
|
|
27
|
+
case 'linux':
|
|
28
|
+
return existsSync('/usr/bin/code') || existsSync('/usr/local/bin/code');
|
|
29
|
+
default:
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
getConfigPath() {
|
|
34
|
+
// VS Code MCP config is per-workspace: .vscode/mcp.json
|
|
35
|
+
return join(process.cwd(), '.vscode', 'mcp.json');
|
|
36
|
+
}
|
|
37
|
+
async writeConfig(apiKey, mcpUrl) {
|
|
38
|
+
const configPath = this.getConfigPath();
|
|
39
|
+
const configDir = dirname(configPath);
|
|
40
|
+
if (!existsSync(configDir)) {
|
|
41
|
+
mkdirSync(configDir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
let config = {};
|
|
44
|
+
if (existsSync(configPath)) {
|
|
45
|
+
try {
|
|
46
|
+
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Start fresh
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// VS Code uses "servers" key
|
|
53
|
+
const servers = config.servers ?? {};
|
|
54
|
+
servers['tostudy'] = buildTostudyServerEntry(apiKey, mcpUrl);
|
|
55
|
+
config.servers = servers;
|
|
56
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
async verify(apiKey, mcpUrl) {
|
|
59
|
+
return verifyHeartbeat(apiKey, mcpUrl);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=vscode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.js","sourceRoot":"","sources":["../../src/ide-handlers/vscode.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Catalyst MCP Setup CLI
|
|
4
|
+
*
|
|
5
|
+
* Configures Claude Code to connect to the Catalyst MCP server.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx @tostudy-ai/mcp-setup
|
|
9
|
+
* npx @tostudy-ai/mcp-setup wizard
|
|
10
|
+
* npx @tostudy-ai/mcp-setup --api-key <key>
|
|
11
|
+
* npx @tostudy-ai/mcp-setup --uninstall
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
|