Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions src/installer/targets/deepcode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* DeepCode target. Writes the MCP server entry into DeepCode's settings
* file (`~/.deepcode/settings.json`). DeepCode has a single user-level
* config — global and local both write here.
*
* See https://deepcode.vegamo.cn/docs/configuration/mcp
*/

import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import {
AgentTarget,
DetectionResult,
InstallOptions,
Location,
WriteResult,
} from './types';
import {
getMcpServerConfig,
jsonDeepEqual,
readJsonFile,
writeJsonFile,
} from './shared';

function configDir(_loc: Location): string {
return path.join(os.homedir(), '.deepcode');
}

function settingsPath(loc: Location): string {
return path.join(configDir(loc), 'settings.json');
}

class DeepcodeTarget implements AgentTarget {
readonly id = 'deepcode' as const;
readonly displayName = 'DeepCode';

supportsLocation(_loc: Location): boolean {
return true;
}

detect(loc: Location): DetectionResult {
const file = settingsPath(loc);
const config = readJsonFile(file);
const alreadyConfigured = !!config.mcpServers?.codegraph;
const installed = fs.existsSync(configDir(loc)) || fs.existsSync(file);
return { installed, alreadyConfigured, configPath: file };
}

install(loc: Location, _opts: InstallOptions): WriteResult {
const files: WriteResult['files'] = [];

// 1. MCP server entry
files.push(writeMcpEntry(loc));

return {
files,
notes: [
'Restart DeepCode for MCP changes to take effect.',
],
};
}

uninstall(loc: Location): WriteResult {
const files: WriteResult['files'] = [];

// 1. MCP server entry
const file = settingsPath(loc);
const config = readJsonFile(file);
if (config.mcpServers?.codegraph) {
delete config.mcpServers.codegraph;
if (Object.keys(config.mcpServers).length === 0) {
delete config.mcpServers;
}
writeJsonFile(file, config);
files.push({ path: file, action: 'removed' });
} else {
files.push({ path: file, action: 'not-found' });
}

return { files };
}

printConfig(loc: Location): string {
const target = settingsPath(loc);
const snippet = JSON.stringify({ mcpServers: { codegraph: getMcpServerConfig() } }, null, 2);
return `# Add to ${target}\n\n${snippet}\n`;
}

describePaths(loc: Location): string[] {
return [settingsPath(loc)];
}
}

function writeMcpEntry(loc: Location): WriteResult['files'][number] {
const file = settingsPath(loc);
const dir = path.dirname(file);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });

const existing = readJsonFile(file);
const before = existing.mcpServers?.codegraph;
const after = getMcpServerConfig();

if (jsonDeepEqual(before, after)) {
return { path: file, action: 'unchanged' };
}
const action: 'created' | 'updated' =
before ? 'updated' : (fs.existsSync(file) ? 'updated' : 'created');
if (!existing.mcpServers) existing.mcpServers = {};
existing.mcpServers.codegraph = after;
writeJsonFile(file, existing);
return { path: file, action };
}

export const deepcodeTarget: AgentTarget = new DeepcodeTarget();
2 changes: 2 additions & 0 deletions src/installer/targets/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { hermesTarget } from './hermes';
import { geminiTarget } from './gemini';
import { antigravityTarget } from './antigravity';
import { kiroTarget } from './kiro';
import { deepcodeTarget } from './deepcode';

export const ALL_TARGETS: readonly AgentTarget[] = Object.freeze([
claudeTarget,
Expand All @@ -26,6 +27,7 @@ export const ALL_TARGETS: readonly AgentTarget[] = Object.freeze([
geminiTarget,
antigravityTarget,
kiroTarget,
deepcodeTarget,
]);

export function getTarget(id: string): AgentTarget | undefined {
Expand Down
2 changes: 1 addition & 1 deletion src/installer/targets/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type Location = 'global' | 'local';
* lookup. New targets add a value here when they're added to the
* registry. Keep these short and lowercase.
*/
export type TargetId = 'claude' | 'cursor' | 'codex' | 'opencode' | 'hermes' | 'gemini' | 'antigravity' | 'kiro';
export type TargetId = 'claude' | 'cursor' | 'codex' | 'opencode' | 'hermes' | 'gemini' | 'antigravity' | 'kiro' | 'deepcode';

/**
* Result of `target.detect(location)`.
Expand Down